题目
给出一个26个大写字母的置换B,
求是否存在一个置换A,,输出Yes/No
思路来源
指南P148
题解
一般考察置换群的性质时,对置换做循环分解
构造一个奇偶置换都存在的置换,
对其作
注意到a、b互不影响,运用交换律分别考虑,有
对于给定的B内的长度为奇的置换,调整顺序即可构造出A
而对于长度为偶的置换,一定需要成对出现才可逆推出A
所以检查所有长度为2,4,…的置换的奇偶性即可
手推半小时,代码五分钟
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int t,len[27];
bool vis[27];
char s[27];
int main(){
scanf("%d",&t);
while(t--){
scanf("%s",s);
memset(vis,0,sizeof vis);
memset(len,0,sizeof len);
for(int i=0;i<26;++i){
int v=s[i]-'A',cnt=0;
for(;!vis[v];v=s[v]-'A'){
vis[v]=1;
cnt++;
}
len[cnt]++;
}
bool ok=1;
for(int i=2;i<=26;i+=2){
if(len[i]%2){
ok=0;
break;
}
}
puts(ok?"Yes":"No");
}
return 0;
}