题目链接
Y1S1,很久没遇到这种有趣的题了。代码很短,一看就懂,就是不好想。
题目大意:
三个长度相等、且只由(A、B、C)3个字符组成的字符串,通过任意次“左/右移”任意一个字符串一位,使得三个字符串在各个位上互不相同,问最小移动次数。
左/右移一位:字符串首尾相连,每个字符左/右移一位,第一个/最后一个移到最后一位/第一位。
代码:
const int inf=0x3f3f3f3f;
const int maxn=5e3+7;
int n,f[3][maxn],cnt=inf;
//f[i][j]表示第i类情况下,偏移量为j是否可行(1表示可行,字符达到不同;0反之)
/*
j偏移方向相同,同时左或同时右都可以,下面我用的同时左
f[i][j]:一共三类
i==1:b相对于a偏移i位——>a[x]与b[(x+i)%n]对应
i==2:c相对于a偏移i位——>a[x]与c[(x+i)%n]对应
i==0:c相对于b偏移i位——>b[x]与c[(x+i)%n]对应
*/
string a,b,c;
int main(){
cin>>a>>b>>c; n=a.size();
for(int i=0;i<3;i++) for(int j=0;j<=n;j++) f[i][j]=1;
for(int i=0;i<n;i++) //偏移量
for(int j=0;j<n;j++){
//b相对于a偏移i位
if(a[j]==b[(i+j)%n]) f[1][i]=0;
//c相对于a偏移i位
if(a[j]==c[(i+j)%n]) f[2][i]=0;
//c相对于b偏移i位
if(b[j]==c[(i+j)%n]) f[0][i]=0;
}
for(int i=0;i<n;i++){ //b相对于a偏移i位
for(int j=0;j<n;j++){ //c相对于a偏移j位
//所以c相对于b偏移(j-i+n)%n位
if(f[1][i]&&f[2][j]&&f[0][(j-i+n)%n]){
//a不动,b、c动
cnt=min(cnt,min(i,n-i)+min(j,n-j));
//a先动,b、c再微调
cnt=min(cnt,max(i,j));
cnt=min(cnt,max(n-i,n-j));
}
}
}
if(cnt==inf) cnt=-1;
out(cnt);
}