티스토리 뷰
[Codeforces 1118B] Tanya and Candies (Prefix Sum,부분합)
hjhj97 2019. 2. 21. 20:44[Codeforces 1118B] Tanya and Candies
n일동안 하루마다 할당된 캔디의 수가 주어진다. 이때 어떤 하루의 캔디를 모두 삭제 한 뒤의 상태(그 이후의 날은 앞으로 한 칸씩 당겨짐)에서 홀수 날 캔디의 합과 짝수 날 캔디의 합이 같은 날이 n일 중에 몇 일인지 찾는 문제이다.
naive하게 푼다면 i번째 날을 계산하기 위해서 1~(i-1)번 째까지 수 + (i+1)~n번 째까지의 캔디를 모두 더하면 되고, 이 풀이는 O(N^2)이다. 하지만 이 문제는 n이 최대 20만이기 때문에 시간이 초과될 것이다. 그래서 관건은 1~(i-1)번째까지, (i+1)~n번 째까지의 캔디의 합을 빨리 구해야한다. 당연하게도 Prefix Sum(부분합)으로 푸는 문제이다. 이 문제에서 한 가지 처리해주어야 할 것은 i번째 날의 캔디를 삭제했다면 그 이후의 날은 한 칸씩 당겨져서 홀짝이 뒤바뀌게 된다.
예를 들어 예시 입력 1에서 7 / 5 5 4 5 5 5 6 이 있을 때 3번째 날(4)를 삭제한다면 그 결과는 5 5 5 5 5 6과 같아진다. 따라서 i번 째 날을 삭제한 뒤, 짝수 날의 합을 구할 때는 i번 째 날 전까지 짝수 날의 합 + i번 째 날 이후의 홀수 날의 합이 되야 한다. 같은 원리로 홀수 날의 합을 구할 때는 i번째 날 전까지 홀수 날의 합 + i번 째 날 이후의 짝수 날의 합이다. 이를 위해서 앞에서부터 누적해나가는 짝수 날의 합(ePre), 홀수 날의 합(oPre), 뒤에서부터 누적해나가는 짝수 날의 합(eSuf), 홀수 날의 합(oSuf)변수가 필요하고 매 루프가 끝날 때마다 갱신해주면 된다.
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 32 33 34 35 36 37 | #include<stdio.h> #define SIZE 200009 int arr[SIZE]; int ePre,oPre,eSuf,oSuf; int main(){ int n; scanf("%d",&n); for(int i=1 ; i<=n ; i++){ int inp; scanf("%d",&inp); arr[i]=inp; if(i&1){ oSuf+=inp; } else eSuf+=inp; } int ans=0; for(int i=1 ; i<=n ; i++){ int even=0,odd=0; if(i&1){ oSuf-=arr[i]; } else eSuf-=arr[i]; even=ePre+oSuf,odd=oPre+eSuf; if(even==odd) ans++; if(i&1){ oPre+=arr[i]; } else ePre+=arr[i]; } printf("%d\n",ans); return 0; } | cs |
'Problem Solving > Etc.' 카테고리의 다른 글
[Codeforces 1141E] Superhero Battle (0) | 2019.03.29 |
---|---|
[Codeforces 1065C] Make It Equal (0) | 2019.03.08 |
15668-방 번호 (0) | 2019.01.08 |
15460-My Cow Ate My Homework(Silver) (0) | 2018.12.12 |
15465-Milk Measurement(Bronze)(set) (0) | 2018.12.12 |