Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

lmlmlm

Codeforces Global Round 25 본문

문제풀기

Codeforces Global Round 25

lml 2024. 4. 7. 10:07

https://codeforces.com/contest/1951

 

E가 1241솔인데 F가 244.

난이도 절벽이 있었고, 나는 F를 못 풀었다.

간만에 div1을 쳐서 점수 하락을 크게 걱정했는데, 이정도면 뭐...

 

A. Dual Trigger

 

당연히 켜진 램프가 홀수 개면 불가능

그리고 켜진게 2개이고 서로 붙어있다면 불가능하다.

이외의 경우에는 i, i + cnt / 2 번째를 동시에 켜면 된다.

 

B. Battle Cows

 

기본적인 아이디어는 K번 cow를 모든 i번자리와 swap해보는 것.

다음과 같이 b와 c를 정의하자

b[i] = max(a[0], a[1], ... a[i - 1])

c[i] = j가 성립한다면, a[k] >= a[i] && a[k] >= a[i + 1] ... && a[k] >= a[i + j - 1] && (i + j == n || a[k] < a[i + j])

 

case 1) b[i] > a[k]라면, i번 자리에 가져다 놓더라도, i - 1번까지의 결과물에게 바로 져버리기에 0

case 2) a[i] > a[k] && k > i라면, i번 자리에 가져다 놓았을 때 min(k - i - 1, c[i + 1] - i - 1) + !!i

-> 왜냐하면 i번 자리부터 고려했을 때 c[i + 1] - i - 1 + !!i번 이길 수 있지만, 결국 k번 자리의 a[i]한테는 진다

case 3) 나머지의 경우 c[i + 1] - i - 1 + !!i

 

대회가 끝나고 나서 생각해보니, b[i] <= a[k]라는 조건이 터지려면 내 앞에 a[x] > a[k]인 x가 없어야 한다.

따라서 그냥 0번째 자리, 1번째 자리, 나보다 큰 첫 번째 자리로 가야 한다.

 

C. Ticket Hoarding

 

일단 제일 티켓이 제일 싼 날짜들에서 구매를 할 것임은 당연하다.

이제는 티켓을 어떤 방식으로 구매하는 것이 제일 싼 방식인지만 결정하면 된다.

예를 들어 (1, 1, 1, 1, 1)의 방식으로 사는 것보다는 한 번에 5장을 사는게 당연히 제일 좋다.

조금 더 고민해보면 (m, m, m, m, ... m, k % m, 0, 0, ... 0, 0)로 구매하는 것이 제일 이득이다.

 

증명해볼 필요도 없이 자명한 편인데 증명을 해보도록 해보자.

어떤 b에 대해서 b[0] + b[1] + ... b[n - 1] = k, b[i] <= m이 성립할 때 b[0] * 0 + b[0] * b[1] + ...의 최솟값을 구하자.

b[0] + .. b[n - 1] = k가 성립하므로 sum(b[i]^2) + sum(2 * b[i] * b[j]) = k^2이 성립한다.

따라서 sum(b[i]^2)을 최소화 시켜주어야 하고, 각 b[x]를 최대화 시켜주는 것이 이득이다.

 

D. Buying Jewels

 

그냥 jewel 2개로 땡친다고 생각하는데 2번째 jewel은 1원으로 처리하자.

1) N = K일때 : 1원으로 하나 팔면 끝

2) K <= (N + 1) / 2일때 : N - K + 1원에 1개 팔고, 나머지 K - 1개를 1원으로 팔면 끝

3) 나머지는 불가능하다

-> pf) 첫 jewel을 1원에 팔면 무조건 N개가 나가버리기에 2원 이상이므로, 최대 N % 2 + N / 2개만 팔 수 있기 때문이다.

-> 따라서 어떻게 팔더라도 N개 미만 팔 때 (N + 1) / 2개를 넘게 팔 수 없다.

 

E. No Palindromes

 

claim) 어떤 string을 non-palindrome으로 쪼개는게 가능하다면 반드시 1개 혹은 2개로 쪼개진다

귀류법) non-palindrome으로 쪼개는 최소 개수가 K > 2라고 가정하자.

순서대로 S[0], S[1], ... S[K - 1]이라고 하고, 이 중에서 제일 길이가 짧은 것은 i번이라고 하자.

K는 최소이므로, (S[p] + S[p + 1] + ... S[i])나 (S[i] + S[i + 1] + .. + S[q])는 반드시 palindrome이다.

1) i가 0이나 N - 1이 아닌 경우

-> S[0],... S[i -1]은 invS[i]로 시작하고, S[i + 1], ... S[K - 1]은 반드시 invS[i]로 끝난다.

-> S[i]는 palindrome이 아니므로 (S[0] + ... S[K - 1])은 palindrome이 될 수 없다.

2) i가 0인 경우 (N - 1이면 그냥 뒤집으면 되니 똑같다)

-> (S[1] + S[2])는 palindrome이므로 S[2]는 invS[1]으로 끝난다

-> (S[0] + S[1] + S[2])는 palindrome이므로 S[0]는 S[1]으로 시작한다.

-> (S[0] + S[1])은 palindrome이므로 S[1]은 invS[1]으로 끝난다.

-> 따라서 S[1]이 palindrome이 되어버리고 모순

 

이후에는 [0, i], [i + 1, n - 1]로 쪼개는게 가능한지만 체크하면 되기 때문에 Z algorithm을 써서 해주면 된다.

사실 케이스워크만으로도 할 수 있다.

 

F. Inversion Composition

 

대충 몇 번 굴려보면 inv(p) <= inv(q) + inv(q * p) <= n * (n - 1) - inv(p)가 성립함을 알 수 있다.

즉, inv(q) + inv(q * p)개가 inv(p)개 아래로 내려올 수도 없고, inv(p)가 일종의 상방으로도 작용한다.

그러면 p에서 inverse가 되는, i < j인데 p[i] > p[j]인 (i, j) 쌍을 잠시 들여다 보자.

이때 inv(q)에서 (p[j] < p[i])쌍으로, inv(q * p)에서 (i, j)쌍으로 들어갔을 때 inverse인지 여부가 반드시 다르다.

즉, 이런 (i, j) 쌍은 inv(q) + inv(q * p)에서 정확히 1번 inverse로 나타난다는 것이다.

반대로 i < j인데 p[i] < p[j]인 (i, j)에 대해서는 q[p[i]] < q[p[j]]라면 0번, q[p[i]] > q[p[j]]라면 2번 inverse로 나타난다.

따라서 이거만 construct하면 된다.

 

일반적으로 inversion의 개수를 construct할 때는 제일 앞에서부터 하나씩 뒤로 보낸다.

그래서 우리도 비슷하게 일단은 생각할 수 있다.

그냥 하던 것과 똑같이 (i, i + 1, ... n - 1, i - 1, i -2, ... 0)로 만들었다고 생각하자 우선.

여기서 어떤 숫자를 한 칸 옮긴다고 해서 inversion 관계가 1개 증가하는게 아니라 2개씩 바뀌곤 한다.

 

그래서 증감이 적당히 유지가 되도록 관리를 해야 한다...

editorial의 construction을 참고하면 될 것 같다.

내가 inv(q) + inv(q * p) 값을 구하는 테스트 파일을 잘못 짜서 이쪽 풀이를 포기했다.

카페인을 너무 많이 먹어서 판단이 흐려졌나보다...

 

'문제풀기' 카테고리의 다른 글

Codeforces Round 939 (Div. 2)  (0) 2024.04.19
AtCoder Beginner Contest 349  (0) 2024.04.13
AtCoder Grand Contest 066  (1) 2024.04.01
AtCoder Regular Contest 174  (0) 2024.03.17
CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)  (0) 2024.03.17
Comments