2016년 낙산사범대학 프로그래밍대회 문제풀이 보고서
A:절단 회문
먼저 모든 하위 문자열이 회문 문자열인지 계산해 낸다. 이 단계의 시간 복잡도는 O(N*N)이어야 한다. 그리고 동적 계획을 해야 한다. 현재의 최소 절단은 앞의 최소 절단이 유도한 것이고 전체적인 최악의 시간 복잡도는 O(N*N)이다.
#include
#include
#define MAXN 1000
#define MIN(a, b) (a < b ? a : b)
int sub[MAXN][MAXN];
void preprocess(char str[], int len) {
int a, b, l, r;
for (a = 0; a < MAXN; ++a) {
for (b = 0; b < MAXN; ++b) {
sub[a][b] = 0;
}
}
for (a = 0; a < len; ++a) {
l = a, r = a;
while (0 <= l && r < len && str[l] == str[r]) {
sub[l][r] = 1;
l -= 1, r += 1;
}
l = a, r = a + 1;
while (0 <= l && r < len && str[l] == str[r]) {
sub[l][r] = 1;
l -= 1, r += 1;
}
}
}
int main() {
int T, dp[1000], len, a, b, c;
char str[1001];
scanf("%d", &T);
while (T--) {
scanf("%s", str);
len = strlen(str);
preprocess(str, len);
//for (a = 0; a < MAXN; ++a) dp[a] = 0;
dp[0] = 1;
for (a = 1; a < len; ++a) {
dp[a] = dp[a - 1] + 1;
for (b = a - 1; b >= 0; --b) {
if (sub[b][a]) {
if (b == 0) dp[a] = 1;
else dp[a] = MIN(dp[a], dp[b - 1] + 1);
}
}
}
printf("%d
", dp[len - 1] - 1);
}
return 0;
}
B:특수 비밀번호 자물쇠
각 버튼은 최대 한 번 누릅니다. 따라서 현재 버튼의 누름 또는 누름 여부는 현재 버튼의 상태와 이전 버튼의 상태에 따라 달라집니다. 따라서 다음 검색을 진행하고 가장자리를 특수하게 처리하면 됩니다.아마도 나의 상태 표시 방법이 약간 타당하지 않은 것 같으니 스스로 고려할 수 있다.
#include
#include
#define INF 30
#define MIN(a, b) (a < b ? a : b)
char str[30], check[30];
void change(int pos, int len) {
if (pos == 0) {
if (str[pos] == '1') str[pos] = '0';
else str[pos] = '1';
if (pos + 1 == len) return;
if (str[pos + 1] == '1') str[pos + 1] = '0';
else str[pos + 1] = '1';
return;
}
if (str[pos - 1] == '1') str[pos - 1] = '0';
else str[pos - 1] = '1';
if (str[pos] == '1') str[pos] = '0';
else str[pos] = '1';
if (pos + 1 == len) return;
if (str[pos + 1] == '1') str[pos + 1] = '0';
else str[pos + 1] = '1';
return;
}
int solve(int pos, int len, int step) {
int res = INF, tmp;
if (pos == len) {
return str[pos - 1] == check[pos - 1] ? step : INF;
}
if (pos == 0) {
tmp = solve(pos + 1, len, step);
res = MIN(res, tmp);
change(pos, len);
tmp = solve(pos + 1, len, step + 1);
res = MIN(res, tmp);
change(pos, len);
return res;
}
if (str[pos - 1] == check[pos - 1]) {
tmp = solve(pos + 1, len, step);
res = MIN(res, tmp);
} else {
change(pos, len);
tmp = solve(pos + 1, len, step + 1);
res = MIN(res, tmp);
change(pos, len);
}
return res;
}
int main() {
int res = INF, len;
while (scanf("%s%s", str, check) != EOF) {
len = strlen(str);
if (len != strlen(check)) printf("impossible
");
res = solve(0, len, 0);
if (res == INF) printf("impossible
");
else printf("%d
", res);
}
return 0;
}
C:최적 시퀀스
현재 최악의 시간 복잡도가 O(N*logN *logN)라는 사고방식이 있는데 코드를 다 치지 못했기 때문에 토론에 관심이 있는 친구는 저를 믿어도 됩니다.
D:문자열 등급
먼저 모든 대문자를 소문자로 바꾸고 빈칸을 하나씩 지워라.
#include
#include
void to_lowercase(char *str) {
int a, len = strlen(str);
for (a = 0; a < len; ++a) {
if (str[a] < 97 && str[a] != ' ') str[a] += 32;
}
}
void remove_space(char *str) {
int a, b = 0, len = strlen(str);
for (a = 0; a < len; ++a) {
if (str[a] != ' ') str[b++] = str[a];
}
for (a = b; a < len; ++a) str[a] = 0;
}
int main() {
char stra[10000], strb[10000];
int a, lena, lenb, res = 1;
gets(stra), gets(strb);
to_lowercase(stra), to_lowercase(strb);
remove_space(stra), remove_space(strb);
lena = strlen(stra), lenb = strlen(strb);
if (lena != lenb) res = 0;
//printf("%s
%s
", stra, strb);
for (a = 0; a < (lena & lenb); ++a) {
if (stra[a] != strb[a]) res = 0;
}
printf("%s
", (res ? "YES" : "NO"));
return 0;
}
E:구간 결합
먼저 순서를 정한 다음에 모든 구간이 연결될 수 있는지 없는지를 판단한다.그러나 데이터 범위 내에서도 해시로 이 문제를 해결할 수 있다.O(N*N)의 최악의 시간 복잡도는 이론적으로 넘길 수 없지만 마지막에 누군가가 이렇게 해서 Accepted를 얻었다는 것은 과학적이지 않다.
#include
typedef struct pair {
int l, r;
}pair;
int compare(const void *a, const void *b) {
return ((pair *)a)->l - ((pair *)b)->l;
}
int main() {
int a, b, l, r, ok = 1, N;
pair region[50000];
scanf("%d", &N);
for (a = 0; a < N; ++a) {
scanf("%d%d", ®ion[a].l, ®ion[a].r);
}
qsort(region, N, sizeof(pair), compare);
l = region[0].l;
r = region[0].r;
for (a = 1; a < N; ++a) {
if (r < region[a].l) {
ok = 0;
break;
}
r = r < region[a].r ? region[a].r : r;
}
if (ok) printf("%d %d
", l, r);
else printf("no
");
return 0;
}
F:문자 루프
이 문제의 중점은 링에 있다. 원래 간단한 문제였어야 했는데 아마도 대다수 학우들이 이런 유형의 문제를 처리하는 경험이 부족했을 것이다.이 문제에 대한 데이터 범위는 매우 작기 때문에 이 문제를 해결하려면 각 열을 배로 늘린 다음에 가장 긴 공공 서브열을 폭력적으로 찾아내면 된다.
#include
#include
#define MAX(a, b) a > b ? a : b
int main() {
char stra[10000], strb[10000];
int a, b, tmp, res = 0, lena, lenb;
scanf("%s%s", stra, strb);
lena = strlen(stra), lenb = strlen(strb);
for (a = 0; a < lena; ++a) stra[a + lena] = stra[a];
for (a = 0; a < lenb; ++a) strb[a + lenb] = strb[a];
stra[lena * 2] = 0, strb[lenb * 2] = 0;
//printf("%s
%s
", stra, strb);
for (a = 0; a < lena * 2; ++a) {
for (b = 0; b < lenb * 2; ++b) {
tmp = 0;
while (tmp + a < lena * 2 &&
tmp + b < lenb * 2 &&
stra[tmp + a] == strb[tmp + b] &&
tmp < lena && tmp < lenb) tmp += 1;
res = MAX(res, tmp);
}
}
printf("%d
", res);
return 0;
}
G:세그먼트 함수
이번 시합에서 프로그램 설계 경기를 접해 본 적이 없는 학생들에게는 아직도 많은 출석 문제가 있는데 이 문제가 그 중의 하나이다.
#include
int main() {
double N, fN;
scanf("%lf", &N);
if (0 <= N && N < 5) fN = -N + 2.5;
else if (5 <= N && N < 10) fN = 2 - 1.5 * (N - 3) * (N - 3);
else if (10 <= N && N < 20) fN = N * 1.0 / 2 - 1.5;
printf("%.3lf
", fN);
return 0;
}
H:최신 정수
열 자리 미만의 숫자, 0이 없으면 K자리를 삭제한다.가능한 모든 수를 직접 들어 가장 작은 것을 찾아라.모든 가능한 수를 다 들면 C(10,5)개밖에 안 되니까 코드 능력만 고찰하는 거죠.
#include
#include
#define MIN(a, b) (a < b ? a : b)
#define INF 1e9
int solve(char *number, int len, int n, int K) {
int a, b;
for (a = 0; a < len; ++a) {
if (n >> a & 1) continue;
K -= 1;
}
if (K) return INF;
for (a = 0, b = 0; a < len; ++a) {
if (n >> a & 1) {
b = b * 10 + (number[a] - '0');
}
}
return b;
}
int main() {
int T, K, len, res, a, b;
char number[10];
scanf("%d", &T);
while (T--) {
scanf("%s%d", number, &K);
len = strlen(number);
res = INF;
for (a = 0; a < 1 << len; ++a) {
b = solve(number, len, a, K);
res = MIN(res, b);
}
printf("%d
", res);
}
return 0;
}
I:하루하루 건강하게 살다
출석 문제.
#include
int main() {
int N, x, ok;
double t;
char flag[5];
scanf("%d", &N);
while (N--) {
scanf("%lf%d%s", &t, &x, flag);
ok = 1;
if (t < 7.0 || t > 8.0) ok = 0;
if (x < 1500) ok = 0;
if (flag[0] == 'N' && flag[1] == 'o') ok = 0;
//printf("flag: %s
", flag);
printf(ok ? "Yes
" : "No
");
}
return 0;
}
J:3개 수 정렬
출석 문제.
#include
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
int main() {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if (a < b) swap(&a, &b);
if (a < c) swap(&a, &c);
if (b < c) swap(&b, &c);
printf("%d %d %d
", a, b, c);
return 0;
}
K:짝수 찾기
먼저 정렬한 다음에 두 개의 순환이 두 개의 다른 수를 매거한 다음에 이분 검색을 통해 집합에 이 두 개의 수의 곱셈이 존재하는지 판단하면 O(N*N*logN)의 최악의 시간 복잡도는Accepted를 얻을 수 있다.인트 폭발에 주의하고 무게 제거에 주의하세요.
#include
#define ll long long
int compare(const void *a, const void *b) {
return (int)((*(ll *)a) - (*(ll *)b));
}
int find(ll *arr, int len, ll val) {
int l = 0, r = len, mid;
while (l < r) {
mid = l + (r - l) / 2;
if (val == arr[mid]) return 1;
if (val < arr[mid]) r = mid;
else l = mid + 1;
}
return val == arr[l];
}
int main() {
int N, res = 0;
ll arr[1000];
int a, b, c;
scanf("%d", &N);
for (a = 0; a < N; ++a) scanf("%lld", arr + a);
qsort(arr, N, sizeof(arr[0]), compare);
for (a = 0; a < N; ++a) {
for (b = a + 1; b < N; ++b) {
if (arr[a] != 1 && find(arr, N, arr[a] * arr[b])) {
res += 1;
}
}
}
printf("%d
", res);
return 0;
}
L:조합수
이 문제는 여러 가지 다른 해법이 있는데, 주로 자신이 공식을 어떻게 유도하는가에 있다.
#include
#define ll long long
int main() {
int N, M;
ll arr[21], a;
for (arr[0] = arr[1] = 1, a = 2; a <= 20; ++a) {
arr[a] = arr[a - 1] * a;
}
while (scanf("%d%d", &N, &M) != EOF) {
if (N < M) {
printf("0
");
continue;
}
printf("%lld
", arr[N] / arr[N - M] / arr[M]);
}
return 0;
}
M:분해 인수
어떤 학우들은 반드시 먼저 소수를 선별할 것이라는 것을 알고 있지만, 자세히 생각해 보면 확실히 필요없다.
#include
int main() {
int N, a;
scanf("%d", &N);
printf("%d=", N);
for (a = 2; a <= N; ++a) {
while (N % a == 0) {
printf("%d", a);
if ((N /= a) != 1) printf("*");
}
}
printf("
");
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.