poj 1026 Cipher 置换群

  对于每个 Block 求出其 循环因子,我这里是用 Vector 动态数组,省事

  循环因子顾名思义就是置换会出现循环. 这样把时间复杂度降下来.

  因为串总长才 200 ,  分别处理每一个循环因子.  可以选择一个一个移动模拟, 也可以一次到位. 我都试了下,都是700+Ms. 

  虽然区别不大, 估计是数据问题吧. 数据量大了肯定影响很大. 

View Code
#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<algorithm>

#include<iostream>

#include<vector>

using namespace std;



vector<int> Q[220];



int a[220], n, num;

bool vis[220];



int check( int s )

{

    for(int i = s; i <= n; i++)

        if( !vis[i] ) return i;

    return -1;

}

void init()

{

    num = 0;

    for(int i = 0; i <= n; i++)

        Q[i].clear();

    memset( vis, 0, sizeof(vis) );

    

    int pos = 1;

    while( ( pos = check(pos) ) != -1 )

    {

        int s = pos;

        while( !vis[s] )

        {

            vis[s] = true;

            Q[num].push_back(s);

            s = a[s];    

        }

        num++;    

        pos++;    

    }

/*    //test OutPut    

//    for(int i = 0; i < num; i++)

//    {

//        

//        printf("(");

//        for(int j = 0; j < Q[i].size(); j++)

//            printf( j == 0 ? "%d" : ",%d", Q[i][j] );

//        printf(")");    

//    }

//    puts("");

//    */

}

int main()

{

    while( scanf("%d", &n) , n )

    {

        for(int i = 1; i <= n; i++)

            scanf("%d", &a[i]);

        init();

        int k;

        char str[220], tmp[220];

        while( scanf("%d%*c", &k), k )

        {

            gets(str+1);

            int len = strlen( str+1 );

            for(int i = len+1; i <= n; i++)

                str[i] = ' ';

        //    for(int i = 1; i <= n; i++)

        //        printf("%c", str[i]); puts("");

            for(int i = 0; i < num; i++)

            {    

                int tot = Q[i].size();

                if( tot <= 1 ) continue;    

                //一次移动多个    

                int t = k%tot;    

                for(int j = tot-t; j < tot; j++)

                    tmp[ Q[i][j] ] = str[ Q[i][j] ];

                for(int j = tot-t-1; j >= 0; j--)

                    str[ Q[i][j+t] ] = str[ Q[i][j] ];    

                for(int j = tot-t; j < tot; j++)

                    str[ Q[i][ j-(tot-t)] ] = tmp[ Q[i][j] ];

                // 一次移动一个

                /*for(int j = 1; j <= (k%tot); j++)

                {

                    char ch = str[ Q[i][tot-1] ];

                    for( int x = tot-1; x > 0; x--)

                        str[ Q[i][x] ] = str[ Q[i][x-1] ];    

                    str[ Q[i][0] ] = ch;    

                }*/

            }

            for(int i = 1; i <= n; i++)

                printf("%c", str[i] ); 

            printf("\n");

        }

        printf("\n");

    }

    return 0;

}

 

你可能感兴趣的:(poj)