题目:
http://codeforces.com/contest/1086/problem/C
题解:
https://blog.youkuaiyun.com/Dream_Lolita/article/details/85239751
或者:
http://codeforces.com/blog/entry/64078
这里要注意的是,不能只用used[ ]和cg[ ],然后再想着如果不行就清零,而是一定要用临时数组use[ ]和tg[ ],第一这样不容易出错,第二,由于这里的check_up和check_down函数中cg[ ]的赋值不是顺序的(从1-->i这样的),而是类似哈希的赋值,所以最终如果某种方式失败后返回前清零,不一定能清除干净!!!!!
代码:
#include<stdio.h>
#include<string.h>
using namespace std;
const int N=1e6+10,M=28;
int n,flag,ff,cnt;
int a[N],b[N],c[N];
int tg[M],cg[M],bo[M];
bool used[M],use[M];
char A[N],B[N],C[N];
void Clear()
{
flag=1;cnt=0;
memset(used,0,sizeof(used));memset(use,0,sizeof(use));memset(tg,0,sizeof(tg));
memset(bo,0,sizeof(bo));memset(cg,0,sizeof(cg));
}
void output()
{
int i,j;
for(i=1;i<=cnt;i++)
{
if(!cg[i]&&tg[i])
cg[i]=tg[i];
if(!used[i]&&use[i])
used[i]=1;
}
for(i=1;i<=cnt;i++)
{
if(!cg[i])
{
for(j=1;j<=cnt;j++)
{
if(!used[j])
{
used[j]=1;
cg[i]=j;
break;
}
}
if(!cg[i])
{
puts("NO");
return;
}
}
}
puts("YES");
for(i=1;i<=cnt;i++)
printf("%c",cg[i]-1+'a');
printf("\n");
return;
}
void checkup(int p)
{
for(int i=p+1;i<n;++i)
{
if(tg[c[i]])
{
if(tg[c[i]]>a[i]) return;
if(tg[c[i]]==a[i]) continue;
ff=0;break;
}
else
{
for(int j=a[i]+1;j<=cnt;++j)
if(!use[j]) {tg[c[i]]=j;use[j]=1;return;}
if(!use[a[i]]) {tg[c[i]]=a[i];use[a[i]]=1;continue;}
ff=0;break;
}
}
}
void checkdown(int p)
{
for(int i=p+1;i<n;++i)
{
if(tg[c[i]])
{
if(tg[c[i]]<b[i]) return;
if(tg[c[i]]==b[i]) continue;
ff=0;break;
}
else
{
for(int j=1;j<b[i];++j)
if(!use[j]) {tg[c[i]]=j;use[j]=1;return;}
if(!use[b[i]]) {tg[c[i]]=b[i];use[b[i]]=1;continue;}
ff=0;break;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Clear();
scanf("%d",&cnt);
scanf("%s%s%s",C,A,B);n=strlen(C);
if(strcmp(A,B)>0) {puts("NO");continue;}
for(int i=0;i<n;++i)
{
a[i]=A[i]-'a'+1,b[i]=B[i]-'a'+1,c[i]=C[i]-'a'+1;
}
int i;
for(i=0;i<n;++i)
{
if(a[i]!=b[i]) break;
if(cg[c[i]])
{
if(cg[c[i]]==a[i]) continue;
else {flag=0;break;}
}
else
{
if(used[a[i]]){flag=0;break;}
cg[c[i]]=a[i],used[a[i]]=1;
}
}
if(i>=n){output();continue;}
if(!flag) {puts("NO");continue;}
if(cg[c[i]])
{
if(cg[c[i]]>a[i] && cg[c[i]]<b[i]) {output();continue;}
if(cg[c[i]]<a[i] || cg[c[i]]>b[i]) {puts("NO");continue;}
ff=1;memcpy(tg,cg,sizeof(cg));memcpy(use,used,sizeof(used));
if(cg[c[i]]==a[i]) checkup(i);
else checkdown(i);
if(ff) {output();continue;}
}
else
{
for(int j=a[i]+1;j<b[i];++j) if(!used[j]) {cg[c[i]]=j;used[j]=1;break;}
if(cg[c[i]]>a[i] && cg[c[i]]<b[i]) {output();continue;}
if(!used[a[i]])
{
memcpy(tg,cg,sizeof(cg));memcpy(use,used,sizeof(used));
ff=1;tg[c[i]]=a[i];use[a[i]]=1;
checkup(i);
if(ff) {output();continue;}
}
if(!used[b[i]])
{
memcpy(tg,cg,sizeof(cg));memcpy(use,used,sizeof(used));
ff=1;tg[c[i]]=b[i];use[b[i]]=1;
checkdown(i);
if(ff) {output();continue;}
}
}
puts("NO");
}
return 0;
}