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 #857 본문

문제풀기

Codeforces Round #857

lml 2023. 4. 27. 00:21

https://codeforces.com/contest/1801

참가했으면 진짜 큰일 났다

 

1A. The Very Beautiful Blanket

 

세로줄과 가로줄을 분리하자. (세로줄만 볼 것)

그러면 일단 만일 같은 세로선위에 있을 때 같은 값을 전부 준다면 문제 조건을 만족할 것이다.

따라서 같은 세로선에는 그냥 같은 값을 주자 (grid[i][j]에 j를 주자는 뜻)

그러면 가로줄에서도 같은 짓을 하는데, 최대한 안 겹치게 해주고 싶다.

따라서 grid[i][j] = (i << 10) ^ j 를 배정해주면 된다.

 

1B. Buying gifts

 

일단 제일 비싼 선물은 B에서 산다고 가정하자. (마지막에 A, B swap해서 한 번 더 해주면 됨)

그러면 B에 대해 큰거부터 정렬을 해두고 앞에서부터 보자.

특정 B[i]가 제일 비싼 선물이 된다고 가정하자.

그러면 우선 그 앞에 있는 B[0], ... B[i - 1]은 무조건 A[0], .. A[i - 1]을 사야하는 것이다. (최대가 B[i]이므로)

만약에 Max(A[0], ... A[i - 1]) = Max_prev > B[i]면 당연히 불가능한 경우가 되는 것.

그런 다음에 나머지 A[i + 1], ... A[n - 1] 중에서 B[i] 미만의 제일 큰 A와 Max_prev 중에 골라서 답을 구해주면 된다.

예외처리를 적당히 해주어야 한다.

 

모든 A값 B값을 넣어두고 순서대로 최대가 되는 경우를 고려하는 방식으로 굳이 swap 없이 단번에도 가능하다.

 

1C. Music Festival

 

일단 각 album에서 쓸모없는 노래들은 쳐내자 (앞의 노래들보다 구린 노래는 모두 없애도 된다.)

그 다음에 각 album들을 제일 좋은 노래를 기준으로 오름차순으로 정렬하자.

set<pii> s에 { (이 앨범의 최대로 좋은 노래), (이 앨범까지 얻을 수 있는 impression) }을 저장해두자.

만약 특정 k 크기의 album의 현재 j번째 노래가 i만큼 듣기 좋다면

최대로 좋은 노래가 i이하인, impression이 제일 큰 것을 set에서 찾으면,

이 앨범을 듣고 난 뒤의 최대 impresison은 Max( k - j + (impression) )이 될 것이다.

노래의 개수만큼 set을 사용하므로 O(nlgn)

 

노래들을 전부 정렬하고 하는 방법도 있다.

아무튼 정렬을 하니까 O(nlgn)

 

1D. The way home

 

우선 공짜로 어디까지 갈 수 있고, 얼마를 들고 있는지 다익스트라로 구하자. (dist1)

 

제일 공연비가 작은 지역부터 보자.

1) 만약에 현재 지점까지 아직 도달을 못했다면 

-> 다른 지역에서 더 공연을 하면 올텐데, 정렬에 의해 그 지역에서 그냥 공연을 더 하는게 여기보다 이득이다.

-> 그래서 그냥 넘어감

2) 이 지점에 도달을 했다면

-> 현재 지역까지 오는데 x번 공연을 했고 y원을 들고 있다고 가정하자.

-> 그러면 이 (x, y)를 들고 다익스트라로 각 지역에 최소 x'번의 공연으로 최대 y'번의 돈을 들고 도착할 수 있는지 구하자

-> 새롭게 구한 dist2와 dist1 중에서 더 이득인 것으로 업데이트한다.

 

dist1에서 그대로 2)에서의 다익을 돌려서 40분정도 시간을 날렸다.

물론 A에서 40분 걸린것도 하자고, B에서 50분 걸린 것도 하자다.

근데 좀 대회가 병신같이 C > D > B가 나온 대회라서 그렇게까지 화나지는 않는다

 

1E. Gasoline prices

 

상당히 놀라운 쿼리이다. path 2개를 선형시간내에 DSU 시키겠다는 의미인데...

이거 물론 HLD로 잘 비비면 될법한 쿼리이고, 실제로 에디토리얼에서도 된다고 한다.

근데 먼 쌉소리지

 

1F. Another n-dimensional chocolate bar

 

대충 느낌은

일단 만약에 a의 약수로 k를 만든다면 무조건 그렇게 만드는 것이 이득이다.

만약에 b이 (a - 1)의 약수라면 대충 (a - 1) / a 만큼의 손해를 입는 것이다.

 

dp[i] : 초콜릿이 i조각이 났을 때의 최대 남은 volume 비율

-> 그러면 현재 p번째 변을 q조각 내버린다면

-> nxt_dp[i * q] = Max( dp[i] * (a[i] - a[i] % q) / a[i] )         현재 dp값들은 실수연산이 이루어짐에 유의

근데 이렇게 하면 마지막에 k곱해지는 것을 관리하기가 어렵다

그래서 dp[1] = k로 정의하고 nxt_dp[i * q] = Max( dp[i] * (a[i] - a[i] % q) / a[i] / q) 로 관리하는게 낫다.

아무튼 이렇게 dp를 모두 구하면 dp[k+]가 답이 될 것이다. 

 

k = 10인 경우에, 현재 초콜릿이 나눠진 개수가 5, 6, 7, 8, 9인 것은 똑같은 상황이다.

-> 어차피 초콜릿을 2배 이상해주어야함은 똑같다.

-> 따라서 ceil(k / i)값에 따라서 숫자들을 모두 묶어줄 수 있다.

-> 이를 이용하면 아까 r = i * q인 하나의 r에 대해서, i로 가능한 숫자가 생각보다 그렇게 많지 않다는 사실을 알 수 있다.

 

습관적으로 코드를 짤 때 inv를 이용해서 짰는데, 복잡도가 빡빡해서 그것만으로 TLE를 받는다.

심지어 이거 double로 해주어야 아마 안전하게 TLE를 통과할 것이다.

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

AtCoder Beginner Contest 300  (0) 2023.04.29
Codeforces Round 868 (Div. 2)  (1) 2023.04.29
AtCoder Beginner Contest 299  (0) 2023.04.24
Codeforces Round 866 (Div. 1, Div.2)  (0) 2023.04.16
AtCoder Beginner Contest 298  (0) 2023.04.16
Comments