• 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/ 希望所写的文章对您有帮助。
  • 相关阅读:
    SQL Server 分页SQL
    element-ui 表格可编辑添加删除
    vue+ element 动态换肤
    与大家分享学习微信小程序开发的一些心得
    Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
    Python 内编写类的各种技巧和方法
    sqlmap-注入方法大全
    kali安装中文输入法完美解决
    kali渗透测试
    parrot-linux,kali-linux,安装输入法
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/13299893.html
Copyright © 2020-2023  润新知