1026 Cipher

描述
Bob和Alice开始使用全新的编码方案。令人惊讶的是,它不是公钥密码系统,但它们的编码和解码基于密钥。他们在1996年2月16日在费城的最后一次会议上选择了密钥。他们选择了一个由n个不同整数组成的密钥,a1; 。 。 。 a,大于零且小于或等于n。编码基于以下原理。消息记录在密钥下方,以便消息中的字符和密钥中的数字相应对齐。位置i处的消息中的字符被写入位置ai处的编码消息中,其中ai是密钥中的对应数字。然后编码的消息以相同的方式编码。该过程重复k次。在kth编码后,他们交换他们的消息。
消息的长度始终小于或等于n。如果消息短于n,则将空格添加到消息的末尾以获取长度为n的消息。
帮助Alice和Bob编写读取密钥的程序,然后编写由k和消息组成的对序列,编码k次,并生成编码消息列表。
输入
输入文件由几个块组成。每个块在第一行中具有数字0 <n <= 200。下一行包含一系列n个数字,这两个数字成对不同,每个数字大于零且小于或等于n。下一行包含整数k和一个由一个空格分隔的ascii字符的消息。这些行以eol结尾,这个eol不属于该消息。该块以带有数字0的单独行结束。在最后一个块之后,在单独的行中有数字0。
输出
输出被分成对应于输入块的块。每个块包含编码的输入消息,其顺序与输入文件中的顺序相同。输出文件中的每个编码消息都具有长度n。在每个块之后有一个空行。
样例输入
10
4 5 3 7 2 8 1 6 10 9
1 Hello Bob
1995 CERC
0
0
样例输出
BolHeol  b
C RCE
/*
POJ 1026
置换
仔细研究一下样例,发现每个字母经过一定次数变换
后一定会回到原来的位置,且这个变换次数肯定不会大于N。
*/
#include<string.h>
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int MAXN=220;
char str[MAXN];//原始的字符串
char ans[MAXN];//最终变换后的字符串,即输出结果

int key[MAXN];//一次变换
int cir[MAXN][MAXN];//每个循环节成员,cir[i][j]表示以i为开始,变换j次后的结果
int num[MAXN];//每个循环节长度
bool vis[MAXN];


int main()
{
   // freopen("in.txt","r",stdin);
   // freopen("out.txt","w",stdout);
    int n,k;
    int cnt;//循环节个数
    while(scanf("%d",&n),n)
    {
        for(int i=1;i<=n;i++)scanf("%d",&key[i]);
        memset(vis,false,sizeof(vis));
        memset(num,0,sizeof(num));
        cnt=0;
        for(int i=1;i<=n;i++)//求所有循环节
        {
            if(vis[i]==false)
            {
                vis[i]=true;
                num[cnt]=0;
                int temp=key[i];
                cir[cnt][num[cnt]++]=temp;
                while(!vis[temp])
                {
                    vis[temp]=true;
                    temp=key[temp];
                    cir[cnt][num[cnt]++]=temp;
                }
                cnt++;
            }

        }
        while(scanf("%d",&k),k)
        {
            gets(str);//第一个是空格
            int len=strlen(str);
            for(int i=len;i<=n;i++)str[i]=' ';
            str[n+1]='\0';
            for(int i=0;i<cnt;i++)
              for(int j=0;j<num[i];j++)
              {
                  ans[cir[i][(j+k)%num[i]]]=str[cir[i][j]];
              }
            ans[n+1]='\0';
            printf("%s\n",ans+1);
        }
        printf("\n");
    }
    return 0;
}

来源:https://www.cnblogs.com/kuangbin/archive/2012/09/03/2669660.html

猜你喜欢

转载自www.cnblogs.com/sweet-ginger-candy/p/11518206.html
今日推荐