Description
题解
显然,这就是二分图匹配字典序最小的解。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 20006
using namespace std;
inline char nc(){
static char buf[100000],*i=buf,*j=buf;
return i==j&&(j=(i=buf)+fread(buf,1,100000,stdin),i==j)?EOF:*i++;
}
inline int _read(){
char ch=nc();int sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
return sum;
}
int n,tot,sum,p[5],ans[maxn],mat[maxn],lnk[maxn],son[maxn],nxt[maxn];
bool vis[maxn];
void add(int x,int y){
nxt[++tot]=lnk[x];son[tot]=y;lnk[x]=tot;
}
bool dfs(int x){
if(!vis[x])return 0;
vis[x]=0;
for(int j=lnk[x];j;j=nxt[j]) if(mat[son[j]]==-1||dfs(mat[son[j]])){
mat[son[j]]=x;return 1;
}
return 0;
}
void hungary(){
memset(mat,255,sizeof(mat));
for(int i=n-1;i>=0;i--){
memset(vis,1,sizeof(vis));
sum+=dfs(i);
}
}
int _abs(int x){return x>0?x:-x;}
int get(int x,int y){return min(_abs(x-y),n-_abs(x-y));}
bool cmp(int x,int y){return x>y;}
int main(){
freopen("distance.in","r",stdin);
freopen("distance.out","w",stdout);
n=_read();
for(int i=0;i<n;i++){
int x=_read();p[1]=i-x,p[2]=i+x,p[3]=i+x-n,p[4]=i+n-x;
sort(p+1,p+5,cmp);
for(int j=1;j<=4;j++)if(p[j]>=0&&p[j]<n&&get(i,p[j])==x)add(i,p[j]+n);
}
hungary();
if(sum<n)return printf("No Answer\n"),0;
for(int i=n;i<2*n;i++)ans[mat[i]]=i-n;
for(int i=0;i<n-1;i++)printf("%d ",ans[i]);printf("%d\n",ans[n-1]);
return 0;
}