您的位置:首页 > 其它

noi 2009 变换序列 贪心

2012-07-11 22:17 309 查看
题意:


#include<iostream>
#include<cmath>
#include<cstring>
#include<set>
#include<cstdio>
using namespace std;
#define MAXN 20000
int n;
int l,r;
int ans[MAXN];
bool use[MAXN];
pair<int,int> part[MAXN];
int a[MAXN];
set<int> opt[MAXN];
int Q[MAXN];
bool bfs(int left,int right)
{
set<int>::iterator te,p;
while(left<=right)
{
int x=Q[left++];
use[x]=1;
te=opt[x].begin();
int y=*te;
if(ans[*te]!=-1)
{
printf("No Answer\n");
return 0;
}
ans[*te]=x;
if(x==part[y].first&&!use[part[y].second])
{
int z=part[y].second;
p=opt[z].find(y);
opt[z].erase(p);
if(opt[z].size()==1)
Q[++right]=z;
}
if(x==part[y].second&&!use[part[y].first])
{
int z=part[y].first;
p=opt[z].find(y);
opt[z].erase(p);
if(opt[z].size()==1)
Q[++right]=z;
}
}
l=left; r=right;
return 1;
}
void solve()
{
set<int>::iterator te,p;
int i;
l=1; r=0;
for(i=0;i<n;i++)
if(opt[i].size()==1)
Q[++r]=i;
if(!bfs(l,r))
return ;
//for(i=0;i<n;i++)
//printf("%d ",ans[i]);
for(i=0;i<n;i++)
if(ans[i]<0)
{
int x=min(part[i].first,part[i].second);
Q[++r]=x;
te=opt[x].begin();
if(te==opt[x].find(i))
te++;
opt[x].erase(te);
if(!bfs(l,r))
return ;
}
for(i=0;i<n-1;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n-1]);
}
int main()
{
memset(ans,0xff,sizeof(ans));
memset(use,0,sizeof(use));
scanf("%d",&n);
int i;
int x,y;
for(i=0;i<n;i++)
{
scanf("%d",a+i);
x=(i+a[i])%n;
y=(i-a[i]+n)%n;
part[i]=make_pair(x,y);
opt[x].insert(i);
opt[y].insert(i);
}
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: