题意: 给出一个A~Z的置换,问是否可以被表示为一个置换的平方(即G=G'*G')
结论: 通过观察可以发现:
一个置换乘上它本身,其中长度为偶数的循环节必然会分裂为两个长度相等的循环节,长度为奇数的循环节还是一个循环节,长度不变
○ 置换中长度为偶数的循环节必然是原置换中的循环节分裂出来的
○ 长度为奇数的循环节有可能是原置换中的循环节分裂出来的
因为只要判断能否被表示,所以可以忽略长度为奇数的循环节,只对长度为偶数的循环节进行考虑即可。
因为一个长度为偶数的循环节分裂出来的两个循环节的长度相等且同为原循环节长度的一半,
所以,只要给出置换中所包含的长度为偶数的循环节能一一配对,那么就必然可以被表示为另一个置换的平方
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) char s[30]; int v[30]; int num[30]; int main() { int i,j,t,k; scanf("%d",&t); while(t--) { scanf("%s",s); clr(v); clr(num); for(i=0;i<26;i++) if(v[i]==0) { j=0; k=i; while(s[k]-'A'!=i) { j++; v[s[k]-'A']=1; k=s[k]-'A'; } j++; v[i]=1; num[j]++; } for(i=2;i<=26;i+=2) if(num[i]%2) break; if(i==28) printf("Yes\n"); else printf("No\n"); } return 0; }