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 }

 

posted @ 2017-10-26 06:54  Kaiser-  阅读(150)  评论(0编辑  收藏  举报