zoukankan      html  css  js  c++  java
  • poj 1026 Cipher (组合数学 置换应用)

    大致题意:Bob and Alice为多个长度为n的信息加密,信息的长度可能小于n,不足n的字符补成空格。先给出n,再给出一个长度为n的数组num[]即加密方式,将原字符串下标为i的字符和下标为num[i]的字符交换。然后给出加密次数和要加密的字符串(多组数据),求出加密后的字符串。具体输入输出格式请参照原题。

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)

    样例:

    Sample Input
     
    10 4 5 3 7 2 8 1 6 10 9
    1 Hello Bob
    1995 CERC
    0
    0
     
    Sample Output
     
    BolHeol b
    C RCE
     
     
    思路:一组数据之间的交换应该还是可以用置换解决,关键求出循环节个数和每个循环中的元素。每个循环节可以搜索出来,同时也能够记录每个循环,难度不大,另外如果一个循环长度为l,那么它加密l次就回到原来初态,所以加密次数对l取余能缩短处理时间。这个题输入输出都比较麻烦,要注意几个细节,每组数据要补全空格,每个case后输出一个空行等等。
     
    貌似有别的解法,没仔细去研究,看到置换就直接去套了,感觉有置换做应该是最快的了。跑了800+ms,够慢的,把循环节个数和循环长度和加密次数都代成200也不超过10^7,看来测试数据够多的。这里应该有一部分代码风格的原因,另外可能有优化的细节没注意,YM 0ms AC的。
     
     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 const int MAXNUM=205;
     5 int num[MAXNUM],cir[MAXNUM][MAXNUM],cnt,n,times;
     6 bool vis[MAXNUM];
     7 char mesg[MAXNUM];
     8 int circle(){  //求出循环节的个数cnt,每个循环节cir的长度len和包含的元素
     9     int i,j,cnt=0;
    10     memset(vis,0,sizeof(vis));
    11     for(i=1;i<=n;i++){
    12         int len=0,temp=i;
    13         while(!vis[temp]){
    14             vis[temp]=true;
    15             cir[cnt][++len]=temp;
    16             temp=num[temp];
    17         }
    18         if(len!=0){
    19             cir[cnt][0]=len;
    20             cnt++;
    21         }
    22     }
    23     return cnt;    
    24 }
    25 void solve(){  //用求出的置换对信息加密,由于每个循环节所表示的置换可以拆成多个对换,所不断以对cir[i][1]和cir[i][j]交换就等价于原置换。
    26     int i,j;
    27     for(i=0;i<cnt;i++){
    28         int len=times%cir[i][0];
    29         while(len--){
    30             for(j=2;j<=cir[i][0];j++){
    31                 char temp=mesg[cir[i][1]];
    32                 mesg[cir[i][1]]=mesg[cir[i][j]];
    33                 mesg[cir[i][j]]=temp;
    34             }
    35         }
    36     }
    37     for(i=1;i<=n;i++)printf("%c",mesg[i]);
    38     printf("\n");
    39 }
    40 int main(){
    41     int i,j;
    42     while(scanf("%d",&n)&&n){
    43         for(i=1;i<=n;i++){
    44             scanf("%d",&num[i]);
    45         }
    46         cnt=circle();
    47         while(scanf("%d",&times)&&times){
    48             memset(mesg,0,sizeof(mesg));
    49             gets(mesg);
    50             for(i=strlen(mesg);i<=n;i++)mesg[i]=' ';
    51             mesg[n+1]='\0';
    52             solve();
    53         }
    54         printf("\n");
    55     }
    56     return 0;
    57 }

     

  • 相关阅读:
    mysql索引
    springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
    java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
    java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
    activiti工作流的web流程设计器整合视频教程 SSM和独立部署
    .Net Core中的ObjectPool
    文件操作、流相关类梳理
    .Net Core中的配置文件源码解析
    .Net Core中依赖注入服务使用总结
    消息中间件RabbitMQ(一)
  • 原文地址:https://www.cnblogs.com/mcflurry/p/2560467.html
Copyright © 2011-2022 走看看