Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
35544K 141ms 内存快要爆了2333【附代妈和思路】其实呢这个每一步都可以唯一确定的。。。搜索剪纸或者dp啥的还是算了吧= = 最简单的从最后一列推第一列是trivial的,就是把0排在前面,1排在后面~ 然后再深入思考以下就可以发现,后面的每一列都差不多,只不过要利用前面的信息,不能破坏已经排好的序,我们可以存放一个order【N】数组,然后记录所有区间断点(我代妈里的intv【】)。在这些断点分割出来的每个区间里来一个小的计数排序,即把0放在前面,1放在后面,重新更新order数组,这样扫描一遍就可以完成,总复杂度是线性。之后下面一行的zeroone值,可以根据这个数组唯一确定了,一共进行N-1次,因此总复杂度为平方级。 #include <iostream> #include <stdio.h> using namespace std; int zeroone[3003][3003]; void print(int N){ for(int j = 0; j < N; j++){ for(int i = 0; i < N; i++){ cout << zeroone[i][j] << " "; } cout << endl; } } int main() { int N; scanf("%d", &N); for(int i = 0; i < N; i++){ scanf("%d", &zeroone[N-1][i]); } bool intv[3004] = {false}; intv[0] = true; intv[N] = true;//开始就一个区间,[0,N) int order[3003]; for(int i = 0; i < N; i++) order[i] = i; for(int i = 0; i < N-1; i++){ int from = i==0? N-1: i-1; int start = 0; int end; int temp[3004]; while(1){ //print(N); //for(int ii = 0; ii < N; ii++) cout << order[ii] << " "; cout << endl; //cout << endl; for(int j = start+1; ; j++){ if(intv[j]) { end = j; break; } } if(end - start == 1){ zeroone[i][start] = zeroone[from][order[start]]; } else{ int offset = 0; int temp_pl = start; for(int ii = start; ii < end; ii++){ if(zeroone[from][order[ii]] == 0){ order[start+offset] = order[ii]; offset ++; } else{ temp[temp_pl] = order[ii]; temp_pl ++; } } intv[start+offset] = true; for(int ii = 0; ii < temp_pl-start; ii++){ order[start+offset+ii] = temp[ii+start]; } for(int ii = start; ii < end; ii++){ zeroone[i][ii] = zeroone[from][order[ii]]; } } if(end == N) break; start = end; } } for(int i = 0; i < N; i++) printf("%d ", zeroone[i][0]); printf("\n"); return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator