/퍼즐-화물열차저번 /퍼즐-아군살리기에 이어, 같은 곳에서 본 다른 문제. 문제의 조건으로는 컨테이너의 위치가 10^9까지 있을 수 있으니... 이게 열차의 최대 길이라 치고, 1) B열차를 한 칸씩 이동시키면서 그때마다 겹치는 컨테이너의 수를 하나씩 찾아가며 센다:
가장 긴 구간끼리 겹쳐야 한다: oo_oo_ooo oo_oo_______ooo 겹치는 구간의 갯수가 많아야 한다: o_o_o_oooo o_o_o_____oooo 짧은 열차가 긴 열차 안에 완전히 들어오는 형태여야 한다: ooooo__o o___ooooo -- Raymundo 2013-1-21 3:33 am
Comments & Trackbacks2진수의 convolution을 FFT로 구하면 O(n log n)인데, KOI 고등부니까 이건 못쓰겠군요.-- inboklee 2013-1-22 12:45 am
-- inboklee 2013-1-25 2:33 pm
O(1) 시간에 1의 갯수를 셀 수 있네요... -- inboklee 2013-1-25 2:41 pm
-- inboklee 2013-1-25 2:54 pm
몇달만에 답을 올리는데, 101110이 있다면 [1,1] [3,5]와 같이 구간으로 표현합니다. 수가 둘이 있으니까 둘 중 구간이 많은 쪽을 m이라고 합시다. 한쪽을 가지고 각 구간을 segment tree에 넣습니다. O(m log m) 시간에 다 넣을 수 있습니다. 다음, 다른 구간들을 차례대로 이 tree에 질의를 하면서 겹치는 부분의 수를 구합니다. 선분이 이동할 때, 체크해야 할 노드 개수가 상수개인지 log m개인지는 좀 헷갈리는데; 어쨌든 이렇게 하면 O(n m log m) 시간에 풀 수 있겠네요. 물론 m log m << n이어야 이 솔루션이 brute force보다 나을 겁니다. -- inboklee 2013-4-17 10:54 am
-- inboklee 2013-4-22 12:43 am
안녕하세요 지나가다가 우연히 블로그에 들러서 문제에 흥미를 가지고 몇 시간 끙끙대다가 결국 풀어서 풀이 써놓고 갑니다... 오랜만에 머리 써보네요 ㅎㅎㅎ #include "stdio.h" #include "algorithm" using namespace std; int N,M; //열차의 개수 int x[1000][2],y[1000][2]; //열차의 정보 int sum,maxvalue,move,slope; //그래프에서 변수들 int i,j,k; struct G{int p,s;}; //position, slope G grp[4000000]; //그래프 정보 저장 int f(G temp1,G temp2){return temp1.p<temp2.p;} //정렬 함수 int main(){ scanf("%d",&N); for(i=0;i<N;i++) scanf("%d%d",&x[i][0],&x[i][1]); scanf("%d",&M); for(i=0;i<M;i++) scanf("%d%d",&y[i][0],&y[i][1]); for(i=0;i<N;i++) for(j=0;j<M;j++){ grp[k].p=x[i][0]+y[j][0]-2; grp[k++].s++; grp[k].p=x[i][0]+y[j][1]-1; grp[k++].s--; grp[k].p=x[i][1]+y[j][0]-1; grp[k++].s--; grp[k].p=x[i][1]+y[j][1]; grp[k++].s++; } sort(grp,grp+k,f); for(i=1;i<k;i++){ slope+=grp[i-1].s; sum+=(grp[i].p-grp[i-1].p)*slope; if(maxvalue<sum){ maxvalue=sum; move=grp[i].p; } } printf("%d",move); } -- GG 2013-7-22 9:46 pm
주인장분류 |
Diary최근 글들
코멘트와 트랙백
옛 글들RSS주요 페이지
이 홈페이지의 인터위키는 다음과 같습니다. GyparkWiki UTF-8 https://gypark.pe.kr/wiki/ |