luogu1963 [NOI2009]变换序列

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, e[10005][2], lnk[20005], d, ans[10005];
bool vis[20005];
bool dfs(int x){
	for(int i=0; i<=1; i++){
		int t=e[x][i];
		if(!vis[t]){
			vis[t] = true;
			if(!lnk[t] || dfs(lnk[t])){
				lnk[t] = x;
				return true;
			}
		}
	}
	return false;
}
int main(){
	cin>>n;
	for(int i=0; i<n; i++){
		scanf("%d", &d);
		e[i][0] = (i + d)%n + n;
		e[i][1] = (i - d + n) % n + n;
		if(e[i][0]>e[i][1])	swap(e[i][0], e[i][1]);
	}
	for(int i=n-1; i>=0; i--){//最后扫的人,也就是编号最小的人更有可能抢到字典序小的答案
		memset(vis, 0, sizeof(vis));
		if(!dfs(i)){
			cout<<"No Answer"<<endl;
			return 0;
		}
	}
	for(int i=0; i<n; i++)
		ans[lnk[i+n]] = i;
	for(int i=0; i<n; i++)
		printf("%d ", ans[i]);
	return 0;
}
posted @ 2018-01-19 07:50  poorpool  阅读(113)  评论(0编辑  收藏  举报