-
CodeTON Round 1 (Div. 1 + Div. 2)코딩 2022. 3. 26. 17:45
이번에 CodeTON Round 1에서 5솔, 308등으로 레드퍼포를 띄웠습니다.
처음에는 A와 C에서 1번씩 틀려서 망했다고 생각했지만, D와 E에서 생각보다 빠르게 답을 찾아서 운 좋게 잘 볼 수 있었던 것 같습니다. 아무래도 Div.1+Div.2다 보니 퍼포가 높게 찍히기도 했네요.
아래는 풀이입니다.
A. Good Pairs
일반성을 잃지 않고 $a_i\leq a_j$라 하면, 수식을 분석했을 때 $a_i\leq a_k \leq a_j$가 수식이 성립할 필요충분조건임을 쉽게 알 수 있습니다. 따라서 배열 중 최댓값과 최솟값의 인덱스를 고르면 됩니다.
더보기(정렬해도 되는 문젠데 이렇게 풀어서 시간도 뺏기고 한 번 틀렸습니다.)
#include <bits/stdc++.h> using namespace std; typedef long long ll; int a[100001]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int T; cin >> T; while(T--) { int n, p=-1e9, q=2e9, idx1=0, idx2=1; cin >> n; for(int i=0; i<n; i++) { cin >> a[i]; if(a[i]>p) { p=a[i]; idx1=i; } if(a[i]<q) { q=a[i]; idx2=i; } } cout << idx1+1 << " " << idx2+1 << "\n"; } }
B. Subtract Operation
임의의 순서에 대해 마지막으로 남는 수는 마지막 두 수가 처음에 몇이었는지에만 의존합니다. 따라서 $a_j-a_i=k$인 서로 다른 $i, j$가 존재하면 답이 YES이며, 그런 쌍이 없다면 NO입니다.
더보기투 포인터로 풀어도 상관없지만, 저는 이분탐색으로 풀었습니다.
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll n, k, a[200001]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int T; cin >> T; while(T--) { cin >> n >> k; for(int i=0; i<n; i++) cin >> a[i]; sort(a, a+n); bool b=0; for(int i=0; i<n; i++) { int p=upper_bound(a, a+n, a[i]-k)-lower_bound(a, a+n, a[i]-k); if(p) {b=1;break;} } if(b) cout << "YES\n"; else cout << "NO\n"; } }
C. Make Equal With Mod
모든 수가 2 이상이라면 가장 큰 원소부터 작은 원소까지 차례대로 $x$로 설정해서 나머지를 구하면 전체가 0으로 맞춰집니다.
0이 포함되어 있다면, 1이 있지 않는 이상 위의 로직대로 할 수 있고, 1이 포함되면 답이 NO가 됩니다.
1이 포함되어 있다면, 전체를 모두 1로 맞춰주어야 하기 때문에 연속된 수가 없다면 $a_i$를 $a_i-1$로 나눈 나머지를 구함으로써 전체를 1로 동일하게 변화시킬 수 있습니다. 연속된 수가 있다면, $a_i$와 $a_i-1$은 동시에 1이 될 수 없기 때문에 답이 NO가 됩니다.
더보기#include <bits/stdc++.h> using namespace std; typedef long long ll; ll n, a[100001]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int T; cin >> T; while(T--) { cin >> n; int cnt=0, z=0, two=0; for(int i=0; i<n; i++) { cin >> a[i]; if(a[i]==1) cnt++; if(a[i]==0) z++; if(a[i]==2) two++; } if(!cnt && !z) { cout << "YES\n"; continue; } if(z) { if(cnt) cout << "NO\n"; else cout << "YES\n"; continue; } sort(a, a+n); bool b=0; for(int i=0; i<n-1; i++) if(a[i]+1==a[i+1]) b=1; if(b) cout << "NO\n"; else cout << "YES\n"; } }
D. K-good
수학문제이기는 하지만 꽤나 좋은 문제라고 생각합니다.
수 $n$에 대해 $k$인 해가 있기 위해서는, $n\equiv 0+1+\cdots+(k-1)\equiv \cfrac{k(k-1)}{2}\ (\mathrm{mod}\ k)$이며, $n\geq \cfrac{k(k+1)}{2}$를 만족해야 합니다.
주어지는 수 $n$이 홀수라면 2가 해에 포함됩니다.
$n$이 짝수일 때의 해만 구하면 됩니다.
임의의 자연수 $X$, 어떤 음이 아닌 정수 $t,\ p$에 대해, $X=2^tp\ (p$는 홀수$)$로 나타낼 수 있습니다.
$n=2^tp\ (p$는 홀수$)$라 설정합니다.
$p\geq 2^{t+1}+1$인 경우, $k=2^(t+1)$일 때 위 조건을 만족하므로 답은 무조건 YES가 됩니다.
$1<p\leq 2^{t+1}$인 경우, $k=p$일 때 위 조건을 만족하므로 답은 YES가 됩니다.
$p=1$일 때는 불가능함을 보일 수 있습니다.
더보기#include <bits/stdc++.h> using namespace std; typedef long long ll; ll n; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int T; cin >> T; while(T--) { cin >> n; ll p=1; while(n%p==0) p*=2; p/=2; ll q=n/p; if(p==1) { cout << "2\n"; continue; } if(q==1) { cout << "-1\n"; continue; } if(q<=p*2) cout << q << "\n"; else cout << p*2 << "\n"; } }
E. Equal Tree Sums
이 문제가 굉장히 참신했습니다.
먼저, 트리를 인접하는 노드들이 같은 색을 가지지 않도록 흰색과 검은색으로 컬러링합니다. 그 후, 흰색 노드는 $\mathrm{deg}$, 검은색 노드는 $-\mathrm{deg}$로 설정합니다. 이렇게 하면 흰색 노드를 없앴을 때는 모든 서브트리의 수가 $1$로, 검은색 노드를 없앴을 때는 모든 서브트리의 수가 $-1$로 됨을 귀납적으로 보일 수 있습니다.
더보기저는 처음 구현할 때는 약간 다르게 했습니다.
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n, ans[100001], b[100001]; bool visited[100001]; vector<int> adj[100001]; void dfs1(int x) { visited[x]=1; for(auto i: adj[x]) if(!visited[i]) { b[i]=-b[x]; dfs1(i); } } void dfs2(int x) { visited[x]=1; for(auto i: adj[x]) if(!visited[i]) { dfs2(i); ans[x]+=b[i]; } ans[x]=b[x]-ans[x]; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int T; cin >> T; while(T--) { cin >> n; for(int i=0; i<=n; i++) adj[i].clear(); memset(b, 0, sizeof(b)); memset(ans, 0, sizeof(ans)); memset(visited, 0, sizeof(visited)); for(int i=0; i<n-1; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } b[1]=1; dfs1(1); memset(visited, 0, sizeof(visited)); dfs2(1); ans[1]--; for(int i=1; i<=n; i++) cout << ans[i] << " "; cout << "\n"; } }
'코딩' 카테고리의 다른 글
백준 16238: 독수리 (0) 2022.03.09 백준 20106: Cave (0) 2022.02.23 백준 20085: Detecting Molecules (1) 2022.02.22 백준 21761: 초직사각형 (3) 2022.01.28 백준 1115: 순열 (0) 2022.01.13