Codeforces Round 868 (Div. 2)
A. A-characteristic (800)Permalink
모든 은 붙어있어도 상관없다.
개가 있다면 이 개가 있고 이 개가 있는데, 그럼 총 쌍의 개수는
이다.
가능한 를 까지 순회해주며 개가 나오는지 확인해주면 된다.
B. Sort with Step (900)Permalink
인 것만 swap이 가능하다는 것은 수열을 개의 그룹으로 나눌 수 있다는 의미이다.
번 째 있는 그룹엔 의 수들만 있어야 하며 자기가 들어가야 할 그룹에 있지 않은 수들의 개수를 bad count라고 하자.
이것이 개라면 정답은 이고, 개라면 정답은 이고 아니라면 이다.
C. Strongly Composite (1300)Permalink
일단 의 모든 수들을 소인수분해하자. 이라서 괜찮다.
이제 모든 소수들만 모아두자.
최대한 그룹의 크기를 최대로 만들어야 하므로 소수들을 어떻게 묶어야 할지 보자.
소수 가 개 있다고 하자.
인 그룹은 가능하다. 왜냐하면 의 합성수는 밖에 없고 소수 개, 합성수 개로 소수가 더 적은 Strongly Composite 수이기 때문이다.
이렇게 모든 같은 소수들에서 두 개씩 뽑아내면 각 소수마다 개의 소수들이 남고, 이 것들 개수의 합을 라고 하자.
이제 서로 다른 소수들은 최소 개씩 묶어야 한다. 따라서 정답에 을 더해준다.
D. Unique Palindromes (1900)Permalink
임을 보자.
이건 시간복잡도와 관련있을 수도 있지만, 알파벳은 최대 개이므로 뭔가 이것과 연관지어 생각하는 것이 문제를 해결할 열쇠이다.
이라면 불가능하다. 왜냐면 하나의 알파벳을 추가할 때 팰린드롬은 최대 개씩 추가되기 때문이다.
같은 이유로 라면 불가능하다. 추가할 수 있는 문자보다 늘어나야할 양이 많다면 불가능하다.
그리고 이라면 불가능하다. 처음 세 개는 무조건 팰린드롬이 개 씩 늘어나게 추가할 수 밖에 없기 때문이다.
이라고 하자.
문제를 푸는 핵심은 어떤 같은 문자를 계속 추가하면 항상 팰린드롬을 1 늘릴 수 있다는 것이다.
따라서 이렇게 길이를 늘릴 때 사용할 문자를 마다 부터 시작해서 처럼 늘려간다.
이제 는 어디다 사용할 것이냐면 팰린드롬을 늘리지 않게 하는 용도로 사용한다.
처음에 정답을 로 두고 만약 그 다음 라고 하자.
문자 개를 추가해야되는데 팰린드롬은 개만(현재 개 이므로) 늘려야 하는 상황이다.
그럼 개를 팰린드롬이 추가되지 않게 사용해야 하므로 를 계속 돌린다.
이후 를 개 추가한다.
이제 다음번엔 에선 를 사용해주고 늘리는 용도론 를 사용해주면 정답을 구성해 나갈 수 있다.
void solve() {
int n, k;
cin >> n >> k;
vector<pi> a(k);
for (int i = 0; i < k; i++) cin >> a[i].fi, a[i].fi--;
for (int i = 0; i < k; i++) cin >> a[i].se;
sort(all(a));
string ans;
char nxt_add_char = 'd';
char nxt_skip_char = 'a';
ans = "abc";
for (int i = 0; i < k; i++) {
int x = a[i].fi, c = a[i].se;
if (x <= 2) {
if (x + 1 != c) {
cout << "NO\n";
return;
}
continue;
}
int diff = x + 1 - sz(ans); // 5 - 3
int add = i == 0 ? (c - 3) : (a[i].se - a[i - 1].se);
if (add > diff) {
cout << "NO\n";
return;
}
int skip = diff - add;
while (skip--) {
ans += nxt_skip_char;
nxt_skip_char = (nxt_skip_char - 'a' + 1) % 3 + 'a';
}
while (add--) {
ans += nxt_add_char;
}
nxt_add_char++;
}
cout << "YES\n" << ans << endl;
}
Comments