POJ 1026 Cipher 置换群

题意:链接

方法:置换群

解析:

挺简单的置换群?

不过第一次太二了想错了。

我以为是直接按照那个序列搞一下置换群的幂就OK了

结果发现,我靠这好多循环也不影响- -那不是逗么。

所以赶紧刹回来求循环。

对于每一个循环内置换,之后就是水题了。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 210
using namespace std;
int n,k;
int a[N];
int b[N][N];
int v[N];
char tmp[N];
char print[N];
int tot;
int lenth;
void getn()
{
    memset(v,0,sizeof(v));
    for(int i=1;i<=n;i++)
    {
        int pt=i;
        if(!v[pt])tot++;
        int cnt=0;
        while(!v[pt])
        {
            v[pt]=1;
            b[tot][++cnt]=a[pt];
            pt=a[pt]; 
        }
        if(cnt!=0)b[tot][0]=cnt;
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        if(n==0)break;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        tot=0;
        getn();
        while(~scanf("%d",&k))
        {
            if(k==0){printf("\n");break;}
            char useless;
            scanf("%c",&useless);
            gets(tmp);
            int len=strlen(tmp);
            while(len<n)tmp[len++]=' ';
            tmp[len]='\0';
            for(int i=1;i<=tot;i++)
            {
                for(int j=1;j<=b[i][0];j++)
                {
                    int tmp2=(j+k)%b[i][0];
                    if(!tmp2)tmp2=b[i][0]; 
                    print[b[i][tmp2]-1]=tmp[b[i][j]-1]; 
                }
            } 
            for(int i=0;i<n;i++)
            {
                printf("%c",print[i]);
            }
            printf("\n");
        }
    }
} 

你可能感兴趣的:(poj)