題意:有一種加密的方法,先給出 n 個數位排列, 然後輸入一個字串,字串長度 <= n。 當字串長度小於n的時候,在其後面加上空白字元,使其長度等於n。
例如 4 5 3 7 2 8 1 6 10 9, Hello Bob, 然後從左至右讓字串的每一個字元與一個數字對應:
4 5 3 7 2 8 1 6 10 9
H e l l o B o b ‘ ’ ‘ ‘
假如加密後的到的新字串用encode[]表示,那麼加密過程就是encod[4] = H, encod[5] = e, encod[3] = l····。
連續加密K次,每一次在前一次得到的資訊之上再加密。
題解:一開始直接類比,然後判斷整個字串的迴圈節。TLE。然後想是不是可以先求出迴圈的K次冪,···沒有下文。最後想到求單個字元的迴圈節,AC。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 300int p[MAXN], loop[MAXN];char mess[MAXN], encode[MAXN];int n, k;void permute (){ int now, i; memset(loop,0,sizeof(loop)); for ( i = 0; i < n; i++ ) { now = p[i]; loop[i] = 1; while ( now != i ) { loop[i]++; now = p[now]; } } for ( i = 0; i < n; i++ ) { int t = k % loop[i]; now = i; while ( t-- ) now = p[now]; encode[i] = mess[now]; }}void print(){ for ( int i = 0; i < n; i++ ) printf("%c",encode[i]); printf("\n");}int main(){ while ( scanf("%d",&n) && n ) { int num, i; for ( i = 0; i < n; i++ ) { scanf("%d",&num); p[num-1] = i; } while ( scanf("%d",&k) && k ) { getchar(); gets(mess); for ( i = strlen(mess); i < n; i++ ) mess[i] = ' '; mess[n] = '\0'; permute(); print(); } printf("\n"); } return 0;}