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

lmlmlm

Codeforces Round #785 (Div. 2) 본문

문제풀기

Codeforces Round #785 (Div. 2)

lml 2022. 5. 1. 02:32

https://codeforces.com/contest/1673

 

평소보다 조금 어려웠고, E에서 수학적 센스가 부족했다.

 

A. Subtle Substring Subtraction

 

Alice는 짝수 길이의 최대 substring을 챙길 것이고 Bob는 나머지를 먹을 것이다.

-> 전체 길이가 짝수면 다 먹고, 홀수라면 맨 앞 혹은 맨 뒤는 버린게 Alice의 점수

 

B. A Perfectly Balanced String?

 

일반성을 잃지않고 적당히 a, b, c ... (ㄱ)이 s에 존재한다고 가정하자

그렇다면 두 개의 같은 알파벳  (ㄴ) ... (ㄴ) 형태의 substring이 있다면, 이 사이에 a, b, ... (ㄱ)이 모두 존재하여야 한다.

만일 (ㄴ) .... (ㄴ) 사이에 (ㄷ)이 존재하지 않는다면, triplet((ㄴ) ... (ㄴ) , (ㄴ), (ㄷ))를 선택할 수 있기 때문이다.

 

C. Palindrome Basis

 

어차피 Palindrome은 그렇게 많지 않다.

모든 palindrome에 대해서 냅색을 해주면 된다. (밑에 풀이 참고)

https://codeforces.com/contest/1673/submission/155445485

 

D. Lost Arithmetic Progression

 

1) C가 B에 속하는지 체크 -> 아니라면 0

2) C의 제일 작은 항을 sC (small C), 제일 큰 항을 bC (big C)라 하자. 똑같이 sB, bB 정의 가능

    만일 sC - d3 < sB 거나 bC + d3 > bB라면 무한히 많은 A가 존재할 수 있다.

     -> (A의 최소값이 한없이 작아지거나 최댓값이 한없이 커짐)

3) 이제 각각의 가능한 A의 공차 d1에 대해서 조건을 만족하는 A의 개수를 세면 된다.

    (d1의 조건 : lcm(d1, d2) = d3) 이므로 d3의 약수 중에서 d1을 찾아내면 된다. 

     -> 이때 만족하는 A의 개수는 왼쪽 끝의 개수가 d3 / d1 오른쪽 끝의 개수가 d3 / d1이니 이 둘을 곱하면 된다.

https://codeforces.com/contest/1673/submission/155446162

 

E. Power or XOR

 

적당히 j개의 항들을 power로 묶어버린 다음에 그런 항이 몇 번 등장하는지 세주면 된다.

-> 이때 20개가 넘는 항들이 power로 묶이지 않기 때문에 그런 항의 수는 20 * n 개 정도이다.

-> b[i], ... b[i + j - 1]이 power로 묶였다고 하고 그 값은 1 << bit라 하자. (단, bit < (1 << 20))

-> 그러면 b[i] 왼쪽과 b[i + j - 1] 오른쪽은 반드시 XOR 기호가 존재한다.

-> 따라서 총 남은 XOR의 개수는 k - 2이고, XOR이 들어갈 수 있는 자리는 n - 2 - j이다. (양끝은 예외처리)

-> 편의상 남은 개수를 left, 자리를 seat라 한다면 C(seat, left) + C(seat, left  + 1) ... C(seat, seat) = S번 등장한다.

-> 어차피 마지막에 모든 값들을 XOR해주기에 이 값의 홀짝성만 중요하다.

-> 이때 C(n, r) = C(n - 1, r - 1) + C(n - 1, r)이므로 이를 적용한다면

-> S = C(seat, 0) + C(seat, 1) + C(seat , 2) +...+ C(seat, seat - left)

      = C(seat - 1, 0) + C(seat - 1, 0) + C(seat - 1, 1) + C(seat - 1, 1) + C(seat - 1, 2) + ...+ C(seat - 1, seat - left)

      = C(seat - 1, seat - left)  -> 이 값이 홀수일 때 답의 bit를 뒤집어주면 된다.

-> C(n, r)의 홀짝성은 lucas theorem으로 인해 (n | r) == n이면 1이고 그게 아니라면 0이다.

https://codeforces.com/contest/1673/submission/155443468

 

F. Anti-Theft Road Planning

 

F를 업솔빙해보았는데 확실히 쉽다는 생각이 들었다.

일단 기본적인 아이디어는 32 x 32 판에 (board[32][32]) 0, 1, ... 1023의 숫자를 부여하면 된다.

-> 예를 들어 이전의 위치가 prev이고 tester가 숫자 x를 주면 나중의 위치를 (prev ^ x)이라고 대답해주면 된다.

다만, board[i][j]의 값으로 naive하게 i * 32 + j를 부여하면 모든 경로의 길이가 48000을 넘어간다.

그렇기에 '적당한 방법'으로 경로의 길이를 줄여주면 된다.

-> 효율적인 방법으로 1, 2, 4, 8, 16 ..., 512를 전체 칸의 절반에 부여하면 된다.

   0    0    0 ...    0    0 

   0    0    0 ...    0    0 

...

512 512 512 ... 512 512

512 512 512 ... 512 512 의 방법으로 배치하면 512가 있는 숫자와 512가 없는 숫자가 인접한 횟수를 최소로 할 수 있다.

 

   0    0    0    0    0

...

128 128 128 128 128 

128 128 128 128 128

...

   0    0    0    0    0 의 방법으로 128을 배치하면 또다시 128의 사용량을 최소로 줄일 수 있다.

 

 

   0    0    0    0    0

...

  32  32  32  32  32

...

   0    0    0    0    0

...

 32   32   32   32  32

...

   0    0    0    0    0 의 방법으로 32를 또 배치할 수 있다.

 

-> 현재는 이를 가로만 고려해주었지만 세로에서 다시 256, 64, 16...을 배치하면 1024개의 칸을 모두 구분할 수 있다.

-> 이때 경로의 합은 47616으로 48000보다 작기에 문제 의도에 부합한다.

https://codeforces.com/contest/1673/submission/155471315

 

 

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

Codeforces Round #783 (Div. 1)  (0) 2022.05.04
AtCoder Beginner Contest 249  (0) 2022.05.02
AtCoder Regular Contest 139  (0) 2022.04.25
Codeforces Global Round 20  (0) 2022.04.24
Educational Codeforces Round 127 (Rated for Div. 2)  (0) 2022.04.23
Comments