Codeforces Round #764 (Div. 3) 후기
- Codeforces Round #764 (Div. 3) 후기
A. Plus One on the Subset
풀이 보기
풀이
1번의 연산으로 배열의 특정 값들을 선택하여 값을 $1$ 증가시킬 수 있다. 이 때 배열의 모든 원소를 같게 만들기 위해 필요한 연산의 최솟값을 찾는 문제이다.
당연히, 최솟값을 최댓값으로 만들기 위해 필요한 연산의 수만큼 필요하지 않을까?
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#define min(a, b) (((a) > (b)) ? (b) : (a))
#define max(a, b) (((a) > (b)) ? (a) : (b))
int testcase;
int main() {
scanf("%d", &testcase);
for (int t = 1; t <= testcase; ++t) {
int l;
scanf("%d", &l);
int minV = (int)(1e9 + 1), maxV = -1;
for (int i = 0; i < l; ++i) {
int a;
scanf("%d", &a);
minV = min(a, minV), maxV = max(a, maxV);
}
printf("%d\n", maxV - minV);
}
return 0;
}
B. Make AP
풀이 보기
풀이
세 수 $a,b,c$가 등차수열을 이루어야한다. 순서를 바꾸지 않아야한다는 조건이 문제를 좀 더 쉽게 한다.
세 수가 등차수열을 이루기 위한 조건은 $a+c=2\times b$이다. 여기서 우리는 최대 1번의 연산을 통해 등차수열을 만들 수 있는지 판단하면 된다. 숫자가 총 3개이므로 가능한 경우는 총 3개이다. 물론 연산을 안한다는 선택지도 있는데, 이건 곱하는 수 $m=1$인 경우라고 생각하자.
- $ma + c = 2b$
- $a + c = 2 mb$
- $a + mc = 2b$
즉, 위의 3가지 경우에 대해 식을 정리하고 $m = \cdots$ 형태로 바꾸면 된다. 이 때 $m$이 양의 정수로만 나오면 된다. 판단하는 방법은 나머지가 0인지 판별하는 과정이면 충분하다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
int main() {
int testcase;
scanf("%d", &testcase);
for (int t = 0; t < testcase; ++t) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
int temp = 2 * b - c;
if (temp > 0 && temp % a == 0) {
printf("YES\n");
continue;
} else {
if ((a + c) % 2 == 0) {
temp = (a + c) / 2;
if (temp > 0 && temp % b == 0) {
printf("YES\n");
continue;
}
}
temp = 2 * b - a;
if (temp > 0 && temp % c == 0) {
printf("YES\n");
continue;
}
}
printf("NO\n");
}
return 0;
}
C. Division by Two and Permutation
풀이 보기
풀이
풀이가 조금 이상하긴 한데 어쨌든 맞았죠? (나중에 더 간단하게 바꾸어야겠다..)
먼저 arr[]
은 입력되는 배열, cnt[i]
은 $i$의 개수를 의미한다. matrix[i][j]
는 $i \rightarrow j$로 가는 방법이 있는지 없는지 알려주는 인접행렬이다.
문제 조건에 의해, arr[]
배열의 원소들을 순열로 바꿔야한다. 즉, 원소의 값들이 $1$부터 $n$까지 1개씩 존재해야한다. 그렇다면 입력된 배열의 원소들은 $n$보다 클 이유가 없다. 가능한 연산 또한 $2$로 나누는 과정밖에 없으므로, 입력 단계에서 미리 처리해두자.
그 다음 순열을 만들기 위한 과정을 거치도록 하자. 큰 수부터 처리하면 이후 연산들이 서로 간섭받지 않을 수 있을 것이다. 각 값들은 정확히 1개씩만 존재해야하므로, 존재하지 않다면 NO
를 출력해버리면 된다. 만약 존재한다면 1개만 남기고 모두 연산을 수행하여 이후로 넘겨버리자.
모든 배열의 원소들이 문제의 조건에 맞게 된다면 YES
를 출력하면 된다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdio.h>
typedef char bool;
const bool true = 1;
const bool false = 0;
#define MAX_IDX (50 + 1)
int arr[MAX_IDX];
int cnt[MAX_IDX];
bool matrix[MAX_IDX][MAX_IDX + 1];
void init() {
for (int i = MAX_IDX - 1; i > 0; --i) {
int temp = i;
while (temp > 0) {
matrix[i][temp] = true;
temp >>= 1;
}
}
return;
}
int main() {
init();
int testcase;
scanf("%d", &testcase);
for (int t = 0; t < testcase; ++t) {
int n;
scanf("%d", &n);
for (int i = 0; i < MAX_IDX; ++i) {
cnt[i] = 0;
}
for (int i = 0; i < n; ++i) {
scanf("%d", arr + i);
while (arr[i] > n) {
arr[i] >>= 1;
}
++cnt[arr[i]];
}
bool isProcessed = false;
for (int i = n; i > 0; --i) {
isProcessed = false;
for (int j = MAX_IDX - 1; j > 0; --j) {
if (matrix[j][i] == true && cnt[j] > 0) {
--cnt[j];
isProcessed = true;
break;
}
}
if (!isProcessed) {
printf("NO\n");
break;
}
}
if (isProcessed) {
printf("YES\n");
}
}
return 0;
}
결과
Contest | Start time | Rank | Solved | Rating change | New rating |
---|---|---|---|---|---|
#764 (Div. 3) | 2022/1/10 23:35 | 3421 | 3 | -9 | 1385 |