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;
}
原文地址:https://www.cnblogs.com/yefeng1627/p/2839792.html