Cipher(置换群 预处理做法、直接做法)

题目链接

题意

题意:有个字符串,按照给定的指环规则进行置换,也就是num[i]和第i个进行指环,求置换后的字符串

思路:找出循环节,所谓的循环结就是,这N个数字进行循环,那么循环N次后,这N个数字肯定还是和第一次是一样的。

第一种做法:预处理每位i  进行j 次到达位置,b[i][j]

第二种做法:处理出所有的循环节,然后 进行 k%len 次直接交换。

#include
#include
using namespace std;
const int N=2e2+10;
int n, a[N], k, b[N][N], p[N];
char t[N], ans[N];
int main()
{
    while(~scanf("%d", &n) && n){
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            p[i] = 0;
            b[i][0] = i;
        }

        for(int i = 1; i <= n; ++i){
            int k = 1;
            while(1){
                ++p[i];
                b[i][k] = a[b[i][k-1]];
                if(b[i][k] == i) break;
                ++k;
            }
        }

        while(1){
            scanf("%d", &k);
            if(k == 0) break;
            getchar();
            string s;
            getline(cin,s);
            for(int i = 0; i < s.size(); ++i) t[i+1] = s[i];
            for(int i = s.size() + 1; i <= n; ++i) t[i] = ' ';
            t[n+1]='\0';
            //cout<

 

第二种

#include
#include
using namespace std;
const int N=2e2+10;
int n, a[N], k, b[N][N], change[N], vis[N], num[N], len;
char t[N], ans[N];
int main()
{
    while(~scanf("%d", &n) && n){
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            vis[i] = 0;
            num[i] = 0;
        }
        len = 0;
        for(int i = 1; i <= n; ++i){
            if(!vis[i]){
                int now = i;
                ++len;
                while(!vis[now]){
                    b[len][num[len]++] = now;
                    vis[now] = 1;
                    now = a[now];
                }
            }
        }
//        for(int i = 1; i < len; ++i) {
//            printf("i:%d num:%d\n",i,num[i]);
//            for(int j = 0; j < num[i]; ++j) printf("%d ",b[i][j]);
//            puts("");
//        }

        while(1){
            scanf("%d", &k);
            if(k == 0) break;
            getchar();
            string s;
            getline(cin,s);
            for(int i = 0; i < s.size(); ++i) t[i+1] = s[i];
            for(int i = s.size() + 1; i <= n; ++i) t[i] = ' ';
            t[n+1]='\0';
            //cout<

 

你可能感兴趣的:(数论--置换群)