POJ 1026 Cipher(置換羣)循環節

Bod 和 Alice 計劃使用一種全新的編碼方案,令人驚訝的是這不是一個公開的公匙密碼,但是他們的編碼基於密匙,在Philadelphia on February 16th他們的會議中選擇了密匙,他們選擇的密匙是一個兩兩不等的整數序列,a1.....an,大於0並且小於等於n,編碼基於一下原則。
下面的信息是關鍵,這樣關鍵的人物信息和數字相對齊,一個字符在i位置,編碼的時候把他放在ai,ai就是相應數字位置的關鍵,並且他們以同樣的編碼信息進行編碼,這個過程重複k次,在k次以後他們交換彼此的編碼。
這段信息的長度小於或者等於n,如果小於n,那麼就在信息的後面能添加空格使它等於n,
寫一個程序完成這個編碼
本題先開始給了n個數,代表編碼的方案,例如

Sample Input

10
4 5 3 7 2 8 1 6 10 9
1 Hello Bob
1995 CERC
0
0

Sample Output

BolHeol  b
C RCE

給出的
4 5 3 7 2 8 1 6 10 9
表示:
第一個位置的字符經過一次置換後會出現在第4位置, 第二位置的編號會到第五位置.....
所以可以得到所有的置換羣爲(1,4,7)(2,5)(3)(6,8)(9,10) 這是經過0次變換的結果。
經過k次變換隻需要單獨的在每個羣裏進行移動就行了,所以,求出置換羣后進行下標取模就行了。
#include<iostream>  
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
#define INF 0x3f3f3f3f
#define bug puts("************")
using namespace std;
const int N=300;
int index[N];
int vis[N];
int num[N];  ///置換羣的大小
int arr[N][N];  ///記錄每個置換羣的內容
char s[N];
char str[N];
int main(){
    int n;
    while(~scanf("%d",&n),n){
        memset(vis,0,sizeof(vis));
        memset(num,0,sizeof(num));
        for(int i=1;i<=n;i++){
            scanf("%d",&index[i]);
        }
        int cnt=0;   ///置換羣的總個數
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                vis[i]=1;
                arr[cnt][num[cnt]++]=i;
                int tmp=index[i];
                while(!vis[tmp]){
                    vis[tmp]=1;
                    arr[cnt][num[cnt]++]=tmp;
                    tmp=index[tmp];
                }
                cnt++;
            }
        }
//        for(int i=0;i<cnt;i++){
//            for(int j=0;j<num[i];j++){
//                printf("%d ",arr[i][j]);
//            }
//            cout<<endl;
//        }
        int m;
        while(~scanf("%d",&m),m){
            gets(s);
            int len=strlen(s);  ///下標0處多讀了一個空格。字符串下標從1開始

            for(int i=len;i<=n;i++) s[i]=' ';
            
            for(int i=0;i<cnt;i++){
                for(int j=0;j<num[i];j++){
                    str[arr[i][(j+m)%num[i]]-1]=s[arr[i][j]];
                }
            }
            str[n]='\0';
            printf("%s\n",str);
        }
        puts("");
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章