UVA12103 贪心+置换
题意:给出26个大写字母的置换B,问是否存在一个置换A,舍得A^2=B,如果存在输出Yes,否则输出No
题解:
研究一下置换A与A^2关系。
假设A=(a1 a2 a3)(b1 b2 b3 b4)
A^2=(a1 a2 a3)(b1 b2 b3 b4)(a1 a2 a3)(b1 b2 b3 b4)
不相交的循环乘法满足交换律。
A^2=(a1 a2 a3)(a1 a2 a3)(b1 b2 b3 b4)(b1 b2 b3 b4)
奇数的两个合并一定是奇数
偶数二个变两个。
所以:两个长度为n的相同循环相乘,当n为奇数结果也是一个长度为n的循环。
当n为偶数,分裂分为两个长度为n/2的循环。
对于n为奇数,可以找到两个奇数循环,使得A^2=B
因为n为偶数的循环只能是两个长度为2n的循环分裂而成的。所以对于任意偶数长度,
循环个数必须是偶数才能配对。
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 int vis[37],cnt[37]; 9 char b[37]; 10 11 int main() 12 { 13 int cas;scanf("%d",&cas); 14 while(cas--) 15 { 16 scanf("%s",b); 17 memset(vis,0,sizeof(vis)); 18 memset(cnt,0,sizeof(cnt)); 19 for (int i=0;i<26;i++) 20 if (!vis[i]) 21 { 22 int j=i,n=0; 23 do{ 24 vis[j]=1; 25 j=b[j]-'A'; 26 n++; 27 }while(j!=i); 28 cnt[n]++; 29 } 30 int flag=1; 31 for (int i=2;i<=26;i+=2) 32 if (cnt[i]%2==1) flag=0; 33 if (flag) printf("Yes\n"); 34 else printf("No\n"); 35 } 36 }