您的位置:首页 > 其它

poj 3128 Leonardo's Notebook(置换的幂)

2016-02-06 10:46 447 查看
http://poj.org/problem?id=3128

大致题意:输入一串含26个大写字母的字符串,能够把它看做一个置换。推断这个置换是否是某个置换的平方。



思路:具体解释可參考url=ihxGpxX7x7ba4dROfWpQ0wlucC03fhDtKuEETsQjYUePKN41PnCBqm0lKrAeDfPXddo8i_1l3834K7iGivkTD-bsu1lAFYS6W55CKqvr13_" style="color:rgb(255,153,0); text-decoration:none">置换群高速幂运算
研究与探讨。


能够先正着考虑一个置换的平方出现什么情况。对于置换中的循环,若其长度为偶数。平方以后一定分成了两个长度相等的循环,若长度是奇数。平方以后仍是一个循环,长度不变。因此。考虑当前置换。若某个循环的长度为偶数,那么它一定是原始置换平方得来的,并且等长度的循环一定有偶数个。对于长度为奇数的循环,它可能是原始置换某个长度为偶数的循环平方得到的。也可能是长度为奇数的循环平方得来的。所以,判定当前置换是否是某个置换的平方等价于推断当前置换
长度为偶数的循环个数是否为偶数个。



#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#define LL long long
#define _LL __int64
#define eps 1e-8
#define PI acos(-1.0)
using namespace std;

const int maxn = 1010;
const int INF = 0x3f3f3f3f;

int a[30];
char s[30];
int vis[30];
int num[30];

bool solve()
{
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
int i;

while(1)
{
for(i = 1; i <= 26; i++)
if(!vis[a[i]])
break;
if(i > 26)
break;
int cnt = 1;
vis[i] = 1;  //不要忘记标记i
int t = a[i];
vis[t] = 1;
while(t != i)
{
vis[t] = 1;
t = a[t];
cnt++;
}
if(cnt % 2 == 0) //是偶数,相应循环个数就加1
num[cnt]++;
}
int flag = 1;
for(int i = 2; i <= 26; i += 2)
{
if(num[i] % 2 != 0)
{
flag = 0;
break;
}
}
if(flag == 1)
return true;
return false;
}

int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%s",s+1);
for(int i = 1; i <= 26; i++)
a[i] = s[i]-'A' + 1;

if(solve())
printf("Yes\n");
else printf("No\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: