poj 1026 置换的应用(小试牛刀)
昨天晚上刚刚看完那个有关置换的应用,今天就试着自己做一下poj的1026题。
题目链接:http://poj.org/problem?id=1026
题目大意:输入n个数,输入n个字符,若输入不够,用空格代替,要求对字符串进行k次迭代,迭代完成后即可得到输出。
此处用“-”代替空格
得到的循环有[1 4 7] [2 5] [3] [6 8] [9 10]
易证:如果k为循环里面元素的个数的倍数,那么该循环不变。
因此对于k次迭代,实际上只需进行x次。( x=k%numl )numl为循环里面元素的个数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=206; 7 struct{ 8 int id, num; 9 }cow[maxn]; ///应用结构体建立置换关系 10 char a[maxn]; ///a为起始字符串 11 char mid[maxn]; ///mid为循环中涉及到的字符 12 int rem[maxn]; ///记录循环中的元素 13 bool flag[maxn]; ///判断是否经历过该点 14 15 void solve(int n,int m) 16 { 17 memset( flag, 0, sizeof flag); 18 for(int i=1;i<=n;i++){ 19 int quan=0; 20 if(!flag[i]){ 21 memset( rem, 0, sizeof rem); 22 flag[i]=true; 23 rem[++quan]=cow[i].id; 24 int next=cow[i].num; 25 while(!flag[next]){ 26 flag[next]=true; 27 rem[++quan]=cow[next].id; 28 next=cow[next].num; 29 } 30 // cout << "quan=" << quan <<endl; 31 int cheek; 32 cheek=m%quan; 33 if(cheek==0) continue; 34 next=quan-cheek+1; 35 for(int j=1;j<=quan;j++){ 36 if(next>quan) next=next-quan; 37 mid[j]=a[rem[next]]; 38 next++; 39 } 40 for(int j=1;j<=quan;j++){ 41 a[rem[j]]=mid[j]; 42 } 43 } 44 } 45 for(int i=1;i<=n;i++) 46 printf("%c",a[i]); 47 printf("\n"); 48 } 49 50 int main() 51 { 52 int n; 53 while( ~scanf("%d",&n)&&n){ 54 for(int i=1;i<=n;i++){ 55 cow[i].id=i; 56 scanf("%d",&cow[i].num); ///建立关系 57 } 58 int m; 59 while( ~scanf("%d",&m)&&m){ 60 getchar(); 61 int len; 62 for(len=1;len<=n;len++){ 63 scanf("%c",&a[len]); 64 if(a[len]=='\n') break; ///输入a 65 } 66 if(len<=n){ 67 for(;len<=n;len++) 68 a[len]=' '; ///补空格 69 } 70 // for(int i=1;i<=n;i++) 71 // printf("%c",a[i]); 72 solve(n,m); 73 } 74 printf("\n"); 75 } 76 return 0; 77 }
实际上,可以直接记录循环节,然后对字符串直接操作。时间复杂度大大缩小。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=206; 7 8 char a[maxn],out[maxn]; ///a为起始字符串 9 int cir[maxn][maxn],rem[maxn],cow[maxn]; ///记录循环中的元素 10 bool flag[maxn]; ///判断是否经历过该点 11 12 int main() 13 { 14 int n; 15 while( ~scanf("%d",&n)&&n){ 16 memset( flag, 0, sizeof flag); 17 memset( cir, 0, sizeof cir); 18 memset( rem, 0, sizeof rem); 19 for(int i=1;i<=n;i++){ 20 scanf("%d",&cow[i]); ///建立关系 21 } 22 int num=0; 23 for(int i=1;i<=n;i++){ 24 if(!flag[i]){ 25 flag[i]=1; 26 cir[num][rem[num]++]=cow[i]; 27 int next=cow[i]; 28 while( !flag[next]){ 29 flag[next]=1; 30 next=cow[next]; 31 cir[num][rem[num]++]=next; 32 } 33 num++; 34 } 35 } 36 37 int m; 38 while( ~scanf("%d",&m)&&m){ 39 gets(a); 40 int len=strlen(a); 41 for(int i=len;i<=n;i++) a[i]=' '; 42 a[n+1]='\0'; 43 for(int i=0;i<num;i++){ 44 for(int j=0;j<rem[i];j++){ 45 out[cir[i][(j+m)%rem[i]]]=a[cir[i][j]]; 46 } 47 } 48 out[n+1]='\0'; 49 printf("%s\n",out+1); 50 } 51 52 printf("\n"); 53 } 54 return 0; 55 }
参考代码:https://www.cnblogs.com/kuangbin/archive/2012/09/03/2669660.html