Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

35544K 141ms 内存快要爆了2333【附代妈和思路】

Posted by KatrineYang at 2016-07-25 09:19:04 on Problem 1147
其实呢这个每一步都可以唯一确定的。。。搜索剪纸或者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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator