• 2011年选拔赛C本科


    考试时间为4小时。

    所填写的代码不超过一条语句(即不能出现分号)。

    考生的程序只有能运行出正确结果的时候才有机会得分。

    选手的程序必须是通用的,不能只对试卷中给定的数据有效。

    不能使用c++特性

    1. 代码填空 (满分3分)
      神秘的三位数
      有这样一个3位数,组成它的3个数字阶乘之和正好等于它本身。即:abc = a! + b! + c!下面的程序用于搜索这样的3位数。请补全缺失的代码。

     

     1 /*
     2   参考答案: 
     3   x > 0
     4   
     5   或者 0<x
     6   或者 x
     7 */
     8 
     9 
    10 #include "stdafx.h"
    11 
    12 int main(int argc, char* argv[])
    13 {//这个程序主要就是把0到9的阶乘存在了数组里 
    14     int JC[] = {1,1,2,6,24,120,720,5040,40320,362880};
    15     int i;
    16     for(i=100; i<1000; i++)
    17     {
    18         int sum = 0;
    19         int x = i;
    20         while(x>0)  // 填空
    21         {
    22             sum += JC[x%10];
    23             x /= 10;
    24         }
    25         if(i==sum) printf("%d\n", i);
    26     }
    27 
    28     return 0;
    29 }

     

    2. 代码填空 (满分4分)

      歌赛新规则

       歌手大赛的评分规则一般是去掉一个最高分,去掉一个最低分,剩下的分数求平均。当评委较少的时候,如果我们只允许去掉一个分数,该如何设计规则呢? 有人提出:应该去掉与其余的分数(还是他自己的分数不是其他选手,从下面的代码可以看出double t = x[i] - sum / (n-1),而且题目是针对某一个选手说的,原来理解错了)平均值相差最远的那个分数。即“最离群”的分数。 以下的程序用于实现这个功能。其中x存放所有评分,n表示数组中元素的个数。函数返回最“离群”的那个分数值。

     1 /*
     2   答案:j != i
     3 
     4   注意逻辑等价形式
     5    i != j
     6    i-j != 0
     7    i-j   (比较变态)
     8 */
     9 
    10 #include "stdafx.h"
    11 
    12 double score(double x[], int n)
    13 {
    14     int i,j;
    15     double dif = -1;
    16     double bad;
    17     for(i=0; i<n; i++)
    18     {
    19         double sum = 0;
    20         for(j=0; j<n; j++)//想想这个求和为什么每次都要执行呢,就是因为是其余数的平均数 
    21         {
    22             if( j != i ) sum += x[j];//填空 
    23         }
    24         double t = x[i] - sum / (n-1);
    25         if(t<0) t = -t;
    26         if(t>dif)
    27         {
    28             dif = t;
    29             bad = x[i];
    30             printf("%d, %f\n", i, x[i]);
    31         }
    32     }
    33     
    34     return bad;
    35 }
    36 
    37 
    38 
    39 int main(int argc, char* argv[])
    40 {
    41     double x[] = {40,20,30,10,60};
    42     printf("%f\n", score(x,5));
    43     
    44     return 0;
    45 }

    3. 代码填空 (满分4分)

      反转串

      我们把“cba”称为“abc”的反转串。 下面的代码可以把buf中的字符反转。其中n表示buf中待反转的串的长度。请补充缺少的代码。

     1 /*
     2   答案:reverse_str(buf+1,n-2)
     3 
     4   注意数组与指针的语法等价性:
     5   buf + 1 等价  &buf[1]
     6 
     7   reverse_str(++buf,n-2)   (比较变态)
     8 */
     9 
    10 
    11 #include "stdafx.h"
    12 
    13 void reverse_str(char* buf, int n)
    14 {
    15     if(n<2) return;
    16     char tmp = buf[0];
    17     buf[0] = buf[n-1];
    18     buf[n-1] = tmp;
    19     /*
    20      这个空,题目上说的是“其中n表示buf中待反转的串的长度”,直觉告诉我应该填如下的答案,可是一会觉得reverse_str(buf+1,n-1)
    21      才合适 ,转念再一想buf表示的是数组的首地址,自增后 数组等于说是从第二个位置开始啦,原来第一个元素的内存地址找不到了 ,这时必需要知道的是数组的长度 ,(n-1)
    22      并不是数组的最后一个位置,因为数组的首地址已经变啦,若是想用起始地址来表示,则 reverse_str(buf,start+1,end-1)
    23      */
    24     reverse_str(buf+1,n-2);   // 填空,第二次做的时候第二个空又填写成了n-1,没运行,看来每道题必须都要运行
    25 }
    26 
    27 
    28 int main(int argc, char* argv[])
    29 {
    30     char x[] = "1234567";
    31     reverse_str(x, 7);
    32     printf("%s\n", x);
    33     while(1); 
    34 
    35     return 0;
    36 }

    4. 代码填空 (满分5分)

      n进制小数

      将任意十进制正小数分别转换成2,3,4,5,6,7,8,9进制正小数,小数点后保留8位,并输出。例如:若十进制小数为0.795,则输出:  十进制正小数 0.795000 转换成 2 进制数为: 0.11001011  十进制正小数 0.795000 转换成 3 进制数为: 0.21011011  十进制正小数 0.795000 转换成 4 进制数为: 0.30232011  十进制正小数 0.795000 转换成 5 进制数为: 0.34414141  十进制正小数 0.795000 转换成 6 进制数为: 0.44341530  十进制正小数 0.795000 转换成 7 进制数为: 0.53645364  十进制正小数 0.795000 转换成 8 进制数为: 0.62702436  十进制正小数 0.795000 转换成 9 进制数为: 0.71348853 以下代码提供了这个功能。其中,dTestNo表示待转的十进制小数。iBase表示进制数。

     1 /*
     2   答案:
     3   空1:  (int)dTestNo   (2分)
     4   空2:  dTestNo>=1.0   (3分)
     5 
     6   注意等价形式,如不能判定,代入程序进行运行试验
     7 */
     8 
     9 #include "stdafx.h"
    10 
    11 void fun(double dTestNo, int iBase)
    12 {
    13     int iT[8];
    14     int iNo;
    15     
    16     printf("十进制正小数 %f 转换成 %d 进制数为: ",dTestNo, iBase);
    17     
    18     for(iNo=0;iNo<8;iNo++)
    19     {
    20         dTestNo *= iBase;
    21         iT[iNo] = (int)dTestNo;    // 填空1,这个填对了,不过当时还有些小怀疑 ,第二次做的时候,第二个空我知道意思,就是看是否有整数部分,写成了dTestNo!=0,未注意是double
    22         if(dTestNo>=1.0) dTestNo -= iT[iNo];  // 填空2,这个判断是否有整数部分,我写的是 (dTestNo> iT[iNo],带入了也可以,后边的自动转为double)
    23     }
    24     
    25     printf("0.");
    26     for(iNo=0; iNo<8; iNo++) printf("%d", iT[iNo]);//小数部分:成基数取整正排列 
    27     printf("\n");
    28 }
    29 
    30 int main (int argc, char* argv[])
    31 {    
    32     double dTestNo= 0.795;
    33     int iBase;
    34     
    35     for(iBase=2;iBase<=9;iBase++)
    36         fun(dTestNo,iBase);
    37     while(1); 
    38     printf("\n");
    39 
    40     return 0;
    41 }

    5. 代码填空 (满分6分)

      轮换

      串“abcd”每个字符都向右移位,最右的移动到第一个字符的位置,就变为“dabc”。这称为对串进行位移=1的轮换。同理,“abcd”变为:“cdab”则称为位移=2的轮换。 下面的代码实现了对串s进行位移为n的轮换。请补全缺失的代码。

     1 /*
     2   答案:
     3   空1:  len+1     (2分)
     4   空2:  0         (4分)
     5 
     6 注意:
     7 空2 等价形式,可以是:
     8 '\0'  
     9 (char)0  
    10 NULL
    11 
    12 如不能断定,需要代入测试
    13 比如:
    14 空2:s[len]  就比较变态,但可行。
    15 */
    16 
    17 #include "stdafx.h"
    18 #include "string.h"
    19 #include "stdlib.h"
    20 
    21 //以前做过这道题,不过用的是分治,两部分先分别倒转,最后再倒转 
    22 void shift(char* s, int n)
    23 {
    24     char* p;
    25     char* q;
    26     int len = strlen(s);
    27     if(len==0) return;
    28     if(n<=0 || n>=len) return;
    29     
    30     char* s2 = (char*)malloc(len+1);   // 填空1,不太明白,而且感觉设置这个空没什么意义,一般要超越10% ,因为长度不包括'\0'
    31     p = s;
    32     q = s2 + n % len;//从q的定义看出,貌似功能是从q开始把前半段存入,从下面while的功能看出我的猜测是对的,哈哈……。 
    33     while(*p)
    34     {    
    35         *q++ = *p++;//*和++优先级相同且结合方向均是自右向左,所以 *q++等价于*(q++) 
    36         if(q-s2>=len)//q到底;两个指向数组的指针相减后是个实数 
    37         {
    38                //注意该语句块内没有break,执行if时q到头了,而p并没有到头 
    39             *q = 0;// 填空2,'\0' , (char)0 , NULL
    40             q = s2;//p并没有到头,所以下次继续执行while
    41                //p不变 
    42         }
    43     }
    44     strcpy(s,s2);
    45     free(s2);
    46 }
    47 
    48 int main(int argc, char* argv[])
    49 {
    50     char x[] = "abcdefg";
    51     shift(x,2);
    52     printf("%s\n", x);// 原来是x,最后输出的还是x,说明对x传址调用。 
    53     while(1); 
    54     return 0;
    55 }

    6. 代码填空 (满分9分)

      中奖计算

      某抽奖活动的规则是:每位参与者在纸上写下一个8位数的号码。最后通过摇奖的办法随机产生一个8位数字。参与者写下的数字中最多有多少个连续位与开奖号码中的相同,则称为中了几个号。 例如:小张写的数字是:12345678,而开奖号码是:42347856。则称小张中了3个号,因为其中最长的相同连续位是:“234”(不仅要相同,而且要位置相同)。如果小张写的是:87654321,则他只中了一个号。 下面的代码根据传入的参数,返回中了几个号。其中:a表示被评价的号码,b表示摇号产生的数字。

     1 /*
     2    参考答案:
     3    空1:sa[i+j]    (4分)
     4    空2:n = j      (5分)
     5  
     6    注意,指针与数组形式的等价性。
     7    *(sa+i+j) 是一样的
     8  */
     9  
    10  
    11  #include <cstdio> 
    12  #include <string.h>
    13  using namespace std;
    14  
    15  int g(int a, int b)
    16  {
    17      char sa[]="00000000";
    18      char sb[]="00000000";
    19      int n = 0;
    20      int i,j;
    21      
    22      sprintf(sa,"%8d",a);//在stdio头文件里 
    23      sprintf(sb,"%8d",b);
    24      for(i=0; i<8; i++)//后面的是中奖号码
    25      {
    26          for(j=1; j<=8-i; j++)//j表示以i开头共几个相同数字(包括位置相同) 
    27          {
    28              char t = sa[i+j];  // 填空1,以前没看懂,现在知道了,sa[i+j]就是设置字符串结束标志,理解了这个就好办了 
    29              sa[i+j] = 0;
    30              if(strstr(sb, sa+i))//sb表示中奖号码, 
    31              {
    32                  if(j>n) n = j;  // 填空2,返回的是n,而其他地方都没有n相关,所以该式子必是n = ? 
    33              }
    34              sa[i+j] = t;
    35          }
    36      }
    37      
    38      return n;
    39  }
    40  
    41  
    42  int main(int argc, char* argv[])
    43  {
    44      printf("%d\n", g(12345678,42234566));//后面的是中奖号码    
    45      printf("%d\n", g(12345678,12345678));
    46      while(1);
    47      return 0;
    48  }

    7. 代码填空 (满分10分)

      概率问题

      某个袋子中有红球m个,白球n个。现在要从中取出x个球。那么红球数目多于白球的概率是多少呢? 下面的代码解决了这个问题。其中的y表示红球至少出现的次数。 这与前文的问题是等价的。因为如果取30个球,要求红球数大于白球数,则等价于至少取出16((30+1)/2,不管奇偶这个 都是较大者)个红球。请根据仅存的线索,判断程序逻辑,并补全缺少的代码。

      

     1 /*
     2 这个题是要考数学的,确实没做出来 ,说实话我连递归刚开始都没想起来 ,认为
     3 空处是xy的某个公式,反正必和xy有关;后来想想应该是递归,因为那几个return要么是0 要
     4 么是1而实际上概率取二者之间的值,所以是递归。 
     5 */
     6 /*
     7   参考答案:
     8   空1:pro(m-1,n,x-1,y-1)  (5分)
     9   空2:pro(m,n-1,x-1,y)    (5分)
    10 
    11   未知答案代入试验一下(多试验几个样例)
    12 */
    13 
    14 #include "stdafx.h"
    15 
    16 /*
    17 m: 袋中红球的数目
    18 n: 袋中白球的数目
    19 x: 需要取出的数目
    20 y: 红球至少出现的次数
    21 */
    22 double pro(int m, int n, int x, int y)
    23 {
    24     if(y>x) return 0;
    25     if(y==0) return 1;//由于y==0说明下面有y自减 
    26     if(y>m) return 0;
    27     if(x-n>y) return 1;
    28     double p1 = pro(m-1,n,x-1,y-1);  // 填空1
    29     double p2 = pro(m,n-1,x-1,y);    // 填空2,从下面的语句里可看出p2是要取出一个白球,且是无重复,所以mn需要变化 
    30     return (double)m/(m+n) * p1 + (double)n/(m+n) * p2;
    31 }
    32 
    33 
    34 int main(int argc, char* argv[])
    35 {
    36     printf("%f\n",pro(5,5,3,1));
    37     while(1);
    38     return 0;
    39 }

    下面的题目都是编程题,没有标准答案,只有测试用例。

    8. 程序设计(满分15分)

    方阵的主对角线之上称为“上三角”。 请你设计一个用于填充n阶方阵的上三角区域的程序。填充的规则是:使用1,2,3….的自然数列,从左上角开始,按照顺时针方向螺旋填充。

    例如:当n=3时,

    输出:

    1 2 3

    6 4

    5

    当n=4时,

    输出:

    1  2 3 4

    9 10 5

    8  6

    7 当n=5时,输出:   1  2  3  4  5  12 13 14  6  11 15  7  10  8   9 程序运行时,要求用户输入整数n(3~20) 程序输出:方阵的上三角部分。 要求格式:每个数据宽度为4,右对齐

    数据宽度不是4,扣3分(不重复扣分)
    没有右对齐,扣2分(不重复扣分)
    
    本题分数扣完为止
    
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 //正螺旋阵 
     7 void solve_square(int str[][30],int n)//不可int *str[]编译错误,要么这样,要么全局 
     8 {
     9     int i,j,k,t;
    10     int x = 0;//圈数
    11     int num = 1;
    12     for(x=0; x<(n+1)/2; x++)//用i表示易出现理解错误 
    13     {
    14         //正横向
    15         for(i=x; i<n-x; i++)
    16             str[x][i] = num++;
    17             //正竖向 
    18         for(j=x+1; j<n-x; j++)
    19             str[j][n-1-x]= num++;
    20             //逆横向 
    21         for(k=n-x-2; k>=x; k--)
    22             str[n-1-x][k] = num++;
    23         for(t=n-x-2; t>=x+1; t--)
    24             str[t][x] = num++;                        
    25     }     
    26 }
    27 
    28 void solve_tri(int str[][30],int n)
    29 {
    30     int i,j,k,t;
    31     int x = 0;//圈数
    32     int num = 1;
    33     //用i表示易出现理解错误 ,n = 1 2 3,x = 1,推出来的 
    34     for(x=0; x<(n+2)/3; x++)
    35     {
    36         for(i=x; i<=n-1-2*x; i++)
    37             str[x][i] = num++;
    38         for(j=x+1; j<n-2*x; j++)
    39             str[j][n-1-x-j]= num++;//下标相加为(n-1-x-j) 
    40         for(k=n-2-2*x; k>x; k--)
    41             str[k][x] = num++;             
    42     }        
    43 }
    44 
    45 void show_tri(int arr[][30], int n)
    46 {
    47     int i,j;
    48     for(i=0; i<n; i++)
    49     {
    50         for(j=0; j<n-i; j++)
    51             printf("%4d",arr[i][j]);
    52         cout<<endl;    
    53     }  
    54 }
    55 
    56 void show_square(int arr[][30],int n)
    57 {
    58     int i,j;
    59     for(i=0; i<n; i++)
    60     {
    61         for(j=0; j<n; j++)
    62             printf("%4d",arr[i][j]);
    63         cout<<endl;    
    64     }
    65 }
    66 
    67 int main()
    68 {
    69     int i,j,k;
    70     int n;
    71     int arr[30][30];
    72     cout<<"Input a Integer:"<<endl;
    73     while(cin>>n&&n)
    74     {
    75         memset(arr,0,sizeof(arr));
    76         cout<<"----正螺旋----"<<endl; 
    77         solve_square(arr,n);
    78         show_square(arr,n);
    79         cout<<"----上三角螺旋----"<<endl; 
    80         solve_tri(arr,n);
    81         show_tri(arr,n);
    82         cout<<"Input a Integer:"<<endl;
    83     }
    84     return 0;
    85 }
     1 //不知道为什么错 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>//包含malloc,但报错说dev没有 malloc头文件 
     6 using namespace std;
     7 
     8 void free_ptr(int **ptr, int N)
     9 {
    10     int i,j,k;
    11     for(i=0; i<N; i++)
    12     { 
    13         free(ptr[i]);
    14         ptr[i] = NULL;
    15     } 
    16     free(ptr);
    17     ptr = NULL;
    18 }
    19 
    20 void fun(int *pointer[],int from,int to,int num,int n)
    21 {
    22     int i,j,k;
    23     if(n<=0)
    24         return ;
    25     for(j=0; j<n-1; j++)
    26     {
    27         if(pointer[0][j])
    28             return ;
    29         pointer[0][j] = num++;
    30             
    31     }
    32     j = n - 1, i = 0;
    33     for(; i<n&&j>=0; i++,j--)
    34     {
    35         if(pointer[i][j])
    36             return ;
    37         if(i+j==n-1)
    38             pointer[i][j] = num++;
    39     }
    40     for(i=n-2; i>=1; i--)
    41     {
    42         if(pointer[i][0])
    43             return ;
    44         pointer[i][0] = num++;
    45     }
    46     fun((int **)(pointer+(from+1)*n+to+1),from+1,to+1,num,n-3);
    47     //fun(((int **)(pointer+from+1)+to+1),from+1,to+1,num,n-3);
    48 }
    49 
    50 int main()
    51 {
    52     int i,j,k,t;
    53     int **ptr;
    54     int N;
    55     cout<<"Input a Integer:"<<endl;
    56     while(cin>>N)
    57     {
    58         ptr = (int **)malloc(sizeof(int *)*(N+5));
    59         if(NULL==ptr)
    60             return 1;
    61         for(i=0; i<N; i++)
    62         {
    63             ptr[i] = (int *)malloc(sizeof(int)*(N+5));
    64             if(NULL==ptr[i])
    65                 return 1;
    66         }
    67         for(i=0; i<N; i++)
    68             for(j=0; j<N; j++)
    69                 ptr[i][j] = 0; 
    70         fun(ptr,0,0,1,N);
    71         for(i=0; i<N; i++)
    72         {
    73             for(j=0; j<N-i; j++)//若是j<N,则if(0==ptr[i][j]) continue;             
    74             {
    75                     printf("%4d",ptr[i][j]); //%4d后不可加空格啦 ,%-4d则是左对齐    
    76             }
    77             cout<<endl; 
    78         }
    79         free_ptr(ptr,N); 
    80     }
    81     return 0;
    82 }

      

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 
     5 int n;
     6 int a[25][25];
     7 
     8 void solve()
     9 {
    10     int i,j,k;
    11     int cnt = 1;
    12     memset(a,0,sizeof(a));
    13     /*
    14     这是第二次做的,做了好久发现了错误三个内层for循环的i都要乘以2,比如若是n=5,则第二次第一个内层for填的13,若不乘2
    15     14也填了。
    16     第二种方法,加上 if(!a[i][j])if(!a[k][j])if(!a[j][i])而不用乘2,不是全部加上 if(!a[i][j])
    17     */
    18     for(i=0; i<(n+2)/3; i++)
    19     {
    20         for(j=i; j<n-2*i-1; j++)
    21             a[i][j] = cnt++;
    22         k = i;//斜着填 
    23         for(j=n-i*2-1; j>i; j--)
    24             a[k++][j] = cnt++;
    25         for(j=n-i*2-1;j>i; j--)
    26             a[j][i] = cnt++;
    27             
    28     }
    29     
    30     
    31 }
    32 
    33 void print()
    34 {
    35     int i,j,k;
    36     for(i=0; i<n; i++)
    37     {
    38         for(j=0; j<n-i; j++)
    39         {
    40             printf("%4d",a[i][j]);
    41         }
    42         printf("\n");
    43     }
    44     
    45 }
    46 
    47 int main()
    48 {
    49     int i,j,k;
    50     scanf("%d",&n);
    51     solve();
    52     print();
    53     system("pause");  
    54     return 0;
    55 }

    9. 程序设计(满分16分)

    公司发了某商店的购物券1000元,限定只能购买店中的m种商品。每种商品的价格分别为m1,m2,…,要求程序列出所有的正好能消费完该购物券的不同购物方法。 程序输入: 第一行是一个整数m,代表可购买的商品的种类数。 接下来是m个整数,每个1行,分别代表这m种商品的单价。 程序输出:  第一行是一个整数,表示共有多少种方案  第二行开始,每种方案占1行,表示对每种商品购买的数量,中间用空格分隔。 例如: 输入: 2 200 300 则应输出: 2 2  2 5  0  输入: 2 500 800 则应输出: 1 2  0 。

    注意:
    
    多行间的顺序可以不同(不扣分)
    
    同样的内容重复出现,则扣2分(此项错误不重复扣分)
    
    多给出一个答案,则扣除2分
    
    开始不输出答案行数的,扣除2分(多个用例不重复扣)
    不是用空格分隔的,扣除2分(多个用例不重复扣)
    
    本题分数扣完为止
    

     

     1 #include <iostream>
     2  #include <cstring>
     3  using namespace std;
     4  
     5  int cost;
     6  int m;//物品个数 
     7  int *price = new int[m];//物品单价 
     8  int cnt[100];//物品数目 
     9  int total;//方案数目 
    10  int ans[100][100];//每种方案的商品分布 
    11  
    12  void output()
    13  {
    14      int i,j,k;
    15      cout<<total<<endl;
    16      for(i=0; i<total; i++)
    17      { 
    18          cout<<ans[i][0];//不多输出空格 
    19          for(j=1; j<m; j++)
    20              cout<<" "<<ans[i][j];
    21          cout<<endl;
    22      } 
    23  }
    24  
    25  //回溯,第cur种物品分为买或者 不买   
    26  void fun(int cur)
    27  {
    28      if(cost >1000||cur >= m)//因为cur从0开始因此需要加上等号 
    29          return ;
    30      if(1000 == cost)
    31      {
    32          for(int i=0; i<m; i++)
    33              ans[total][i] = cnt[i];
    34          total++;
    35          return ;
    36      }
    37      //选 择第cur种物品
    38      ++cnt[cur];
    39      cost += price[cur];
    40      fun(cur);
    41      //不选择第cur种物品
    42      --cnt[cur];
    43      cost -= price[cur];
    44      fun(cur+1);
    45  }
    46      
    47  int main()
    48  {
    49      int i,j,k;
    50      cin>>m;
    51      for(i=0; i<m; i++)
    52          cin>>price[i];
    53      fun(0);
    54      output();
    55      delete price; 
    56      while(1);
    57      return 0;
    58  }
    59  

    10. 程序设计(满分28分)

    一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复

    ,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如

    下: 1.首先按行填入密钥串。 2.紧接其后,按字母序按行填入不在密钥串中的字母。 3.由于方阵中只有25个位置,最后剩下的那个字母则不需变换。 如果密钥为youandme,则该方阵如下:  y o u a n d m e b c f g h i j k l p q r s t v w x 在加密一对字母时,如am,在方阵中找到以这两个字母为顶点的矩形(红色字体): y o u a n d m e b c f g h i j k l p q r s t v w x

    这对字母的加密字母为该矩形的另一对顶点,如本例中为ob。 请设计程序,使用上述方法对输入串进行加密,并输出加密后的串。 另外有如下规定: 1、一对一对取字母,如果最后只剩下一个字母,则不变换,直接放入加密串中; 2、如果一对字母中的两个字母相同,则不变换,直接放入加密串中; 3、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中; 4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,

    即变换为fd或ih; 5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对

    顶点字母中,与a同行的字母应在前面,在上例中应是ob;同样若待变换的字母对为ta,则

    变换后的字母对应为wo; 6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。 解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。 要求输入形式如下: 从控制台输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符

    串(长度小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写

    字母,不含其它字符。 在标准输出上输出加密后的字符串。 例如,若输入: youandme welcometohangzhou 则表示输入的密钥单词为youandme,形成的正方形如上所示;待加密字符串为

    welcometohangzhou。在正方形中可以找到以第一对字母we为顶点的矩形,对应另一对顶点

    字母为vb,因此加密后为vb,同理可找到与字母对lc,et,oh,ho对应的顶点字母对。而字母

    对om位于上述正方形中的同一列,所以直接以颠倒这两个字母来加密,即为mo,字母对an

    同理。字母对gz中的z不在上述正方形中,因此原样放到加密串中。最后剩一个字母u也原

    样输出。 因此输出的结果为: vbrmmomvugnagzguu

  • 相关阅读:
    第15.9节 PyQt学习入门:使用Qt Designer进行GUI设计的步骤
    PyQt学习随笔:Model/View开发时在view数据项中设置不同角色数据的方法
    PyQt学习随笔:Model/View开发时从Model相关类派生自定义类需要注意的问题
    PyQt学习随笔:重写setData方法截获Model/View中视图数据项编辑的注意事项
    PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法
    Python中高级知识(非专题部分)学习随笔
    clistctrl 虚拟列表
    数字图象处理图片库
    MFC中char*,string和CString之间的转换
    图像分割之(四)OpenCV的GrabCut函数使用和源码解读
  • 原文地址:https://www.cnblogs.com/hxsyl/p/2841711.html
Copyright © 2020-2023  润新知