zoukankan      html  css  js  c++  java
  • poj 1026 Cipher (置换群,循环节)

    poj 1026 Cipher (置换群,循环节)

    POJ - 1026

    题意:

    Bob and Alice started to use a brand-new encoding scheme. Surprisingly it is not a Public Key Cryptosystem, but their encoding and decoding is based on secret keys. They chose the secret key at their last meeting in Philadelphia on February 16th, 1996. They chose as a secret key a sequence of n distinct integers, a1 ; . . .; an, greater than zero and less or equal to n. The encoding is based on the following principle. The message is written down below the key, so that characters in the message and numbers in the key are correspondingly aligned. Character in the message at the position i is written in the encoded message at the position ai, where ai is the corresponding number in the key. And then the encoded message is encoded in the same way. This process is repeated k times. After kth encoding they exchange their message.

    The length of the message is always less or equal than n. If the message is shorter than n, then spaces are added to the end of the message to get the message with the length n.

    Help Alice and Bob and write program which reads the key and then a sequence of pairs consisting of k and message to be encoded k times and produces a list of encoded messages.

    思路:

    把置换群的多组循环节找出来,对于给定的字符串,和置换次数(mathit k),对每个循环节分开处理,置换次数可以对循环节长度取模。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    // #include <bits/stdc++.h>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x)  if(DEBUG_Switch) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    void pvarr_int(int *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%d%c", arr[i], i == n ? '
    ' : ' ');}}
    void pvarr_LL(ll *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%lld%c", arr[i], i == n ? '
    ' : ' ');}}
    const int maxn = 1010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    #define DEBUG_Switch 0
    int n;
    int a[maxn];
    char t[maxn];
    char s[maxn];
    int cnt;
    int vis[maxn];
    std::vector<int> v[maxn];
    void find_loop()
    {
        cnt = 0;
        repd(i, 0, n)
        {
            vis[i] = 0;
            v[i].clear();
        }
        int tot = 0;
        repd(i, 0, n-1)
        {
            if (vis[i] == 0)
            {
                cnt++;
                int id = i;
                while (vis[id] == 0)
                {
                    v[cnt].pb(id);
                    vis[id] = ++tot;
                    id = a[id];
                }
            }
        }
    }
    void solve(int len, int k)
    {
        strcpy(t, s);
        repd(i, 1, cnt)
        {
            int num = sz(v[i]);
            int x = k % num;
            for (int j = 0; j < num; ++j)
            {
    //            cout<<v[i][j]<<" "<<v[i][(j - x + num) % num]<<endl;
                s[v[i][j]] = t[v[i][(j - x + num) % num]];
            }
        }
    }
    int main()
    {
    #if DEBUG_Switch
        freopen("C:\code\input.txt", "r", stdin);
    #endif
        //freopen("C:\code\output.txt","w",stdout);
        while (~scanf("%d", &n) && n)
        {
            repd(i, 0, n - 1)
            {
                a[i] = readint();
                a[i]--;
            }
            find_loop();
            int len;
            int k;
            while (~scanf("%d", &k) && k)
            {
                getchar();
                gets(s);
                len = strlen(s);
                while (len < n)
                {
                    s[len++] = ' ';
                }
                s[len]='';
                solve(len, k);
                printf("%s
    ", s );
                // memset(s, '', sizeof(s));
            }
            printf("
    ");
        }
        return 0;
    }
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    实际运用中DataSet、DataTable、DataRow点滴
    SQL语句AND 和 OR执行的优先级
    CS程序,服务器端弹出MessageBox.Show()之类的UI操作???禁止
    使用动态SQL语句实现简单的行列转置(动态产生列)
    表的行列转置
    统计每种车型的数量
    由CAST()函数在.NET1.1和.NET4.0下处理机制不同所引发的BUG
    转载——网站重构的8点建议
    float,double和decimal类型
    优化DB2缓冲页的大小
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/13299893.html
Copyright © 2011-2022 走看看