procedure2012
It's not worth it to know you're not worth it!

[关键字]:数学 置换群

[题目大意]:给出一组置换,然后要求出把给出的文字按位置置换k此后的信息。

//==========================================================================================================================================

[分析]:首先求出这个置换的循环,并记录循环的长度环每个位置上的值。找到每个位置所属的循环然后它在循环中的位置加k再对循环长度取模就是它的最终位置。

[代码]:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,len,sum,test;
int a[205],c[205][205],belong[205],d[205];
char s[205],s2[205],ch;
bool b[205];

void Solve()
{
    sum=0;
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    memset(belong,0,sizeof(belong));
    memset(d,0,sizeof(d));
    for (int i=1;i<=n;++i)
        if (!b[i])
        {
            ++sum;
            int p=i;
            while (!b[p])
            {
                b[p]=1;
                belong[p]=sum;
                c[sum][++c[sum][0]]=p;
                d[p]=c[sum][0];
                p=a[p];
            }
        }
    /*for (int i=1;i<=sum;++i)
    {
        for (int j=0;j<=c[i][0];++j) printf("%d ",c[i][j]);
        printf("\n");
    }*/
    memset(s2,0,sizeof(s2));
    for (int i=1;i<=n;++i)
    {
        int pos=belong[i],size=c[pos][0];
        s2[c[pos][(d[i]+m-1)%size+1]]=s[i];
        //printf("%d %d\n",i,c[pos][(d[i]+m-1)%size+1]);
    }
    for (int i=n;i>=1;--i)
        if (s2[i]==' ') s2[i]='\0'; else break;
    printf("%s\n",s2+1);
}

int main()
{
    freopen("in","r",stdin);
    freopen("out","w",stdout);
    while (scanf("%d",&n),n)
    {
        if (++test!=1) printf("\n");
        for (int i=1;i<=n;++i) scanf("%d",&a[i]);
        while (scanf("%d",&m),m)
        {
            len=0;
            scanf("%c",&ch);
            while (scanf("%c",&ch),ch!='\n') s[++len]=ch;
            while (len<n) s[++len]=' ';
            s[n+1]='\0';
            Solve();
        }
    }
    return 0;
}
posted on 2012-04-17 11:40  procedure2012  阅读(184)  评论(0编辑  收藏  举报