[关键字]:数学 置换群
[题目大意]:给出一组置换,然后要求出把给出的文字按位置置换k此后的信息。
//==========================================================================================================================================
[分析]:首先求出这个置换的循环,并记录循环的长度环每个位置上的值。找到每个位置所属的循环然后它在循环中的位置加k再对循环长度取模就是它的最终位置。
[代码]:
#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; }