/*======================================================================== 25:螺旋加密 总时间限制: 1000ms 内存限制: 65536kB 描述 Chip和Dale发明了一种文本信息加密技术。他们事先秘密约定好矩阵的行数和列数。 接着,将字符按如下方式编码: 1. 所有文本只包含大写字母和空格。 2. 每个字符均赋予一个数值:空格=0,A=1,B=2,……,Y=25,Z=26。 从左上角开始,按顺时针旋转的方式,将每个字符对应数值的5位二进制数依次填入矩阵。 最后用0将矩阵补充完整。例如,对于信息“ACM”,行列数均为4时,矩阵将被填充为: 0000 1101 0010 1100 其中,A=00001,C=00011,M=01101. 矩阵中的数字按行连起来形成数字串,完成加密。 例子中的信息最终会被加密为:0000110100101100。 输入 一行。首先是两个整数R(1≤R≤20)和C(1≤C≤20),表示行数和列数。 之后是一个只包含大写字母和空格的字符串。字符串的长度≤(R*C)/5。 R和C之间以及C和字符串之间均用单个空格隔开。 输出 一行,为加密后的二进制串。注意你可能需要用0将矩阵补充完整。 样例输入 4 4 ACM 样例输出 0000110100101100 来源 Greater NY 2007 ==========================================================================*/
1 #include<stdio.h> 2 #include<string.h> 3 4 #define localTest 1 5 #define maxR 23 6 #define maxC 23 7 8 int main(int argc, char *argv[]) 9 { 10 int R,C,i,j,t,k; 11 char str[100]; 12 char a[maxR][maxC],dic[27][6],dic2[505]=""; 13 int len; 14 int R2,C2; 15 16 #ifdef localTest 17 freopen("25.in","r",stdin); 18 #endif 19 20 scanf("%d %d ",&R,&C); //注意这里的输入方式 21 gets(str); 22 //printf("%d %d%s\n",R,C,str); 23 24 //初始化a[][]数组 25 for(i=0;i<maxR;i++) 26 for(j=0;j<maxC;j++) 27 { a[i][j]=‘0‘; } 28 29 //提前准备好二进制数据和字母的映射表 30 for(i=0;i<27;i++) 31 { 32 t=i; 33 for(j=4;j>=0;j--) 34 { 35 dic[i][j]=t%2+‘0‘; 36 t=t/2; 37 } 38 dic[i][5]=‘\0‘; 39 //printf("%2d-->%s\n",i,dic[i]); 输出字典做检验 40 } 41 42 len=strlen(str); 43 for(i=0;i<len;i++) 44 { 45 if(str[i]==‘ ‘) strcat(dic2,dic[0]); 46 else 47 { 48 t=str[i]-‘A‘+1;; 49 strcat(dic2,dic[t]); 50 } 51 } 52 //printf("%s\n",dic2);输出检测 53 54 if(R==1)//只有一行 55 { 56 printf("%s",dic2); 57 i=len*5+1; 58 while(i<=C) 59 { 60 printf("0"); 61 i++; 62 } 63 printf("\n"); 64 } 65 else if(C==1)//只有一列 66 { 67 for(i=0;dic2[i]!=‘\0‘;i++) 68 printf("%c\n",dic2[i]); 69 i=len*5+1; 70 while(i<=R) 71 { 72 printf("0\n"); 73 i++; 74 } 75 } 76 else 77 { 78 k=0; 79 i=0;j=0; 80 R2=R;C2=C; 81 while(dic2[k]!=‘\0‘) 82 { 83 for(t=1;t<C&&dic2[k]!=‘\0‘;t++) 84 { a[i][j]=dic2[k];k++;j++;} //填充一个环的上面那一条边 85 for(t=1;t<R&&dic2[k]!=‘\0‘;t++) 86 { a[i][j]=dic2[k];k++;i++;} //填充一个环的右侧那一条边 87 for(t=1;t<C&&dic2[k]!=‘\0‘;t++) 88 { a[i][j]=dic2[k];k++;j--;} //填充一个环的下面那一条边 89 for(t=1;t<R&&dic2[k]!=‘\0‘;t++) 90 { a[i][j]=dic2[k];k++;i--;} //填充一个环的左侧那一条边 91 92 i++;j++; 93 R-=2;C-=2; 94 if(R==1)//只剩下一行 95 { 96 for(t=1;t<=C&&dic2[k]!=‘\0‘;t++,k++) 97 { a[i][j]=dic2[k];j++;} 98 } 99 else if(C==1)//只剩下一列 100 { 101 for(t=1;t<=R&&dic2[k]!=‘\0‘;t++,k++) 102 { a[i][j]=dic2[k];i++;} 103 } 104 } 105 106 for(i=0;i<R2;i++)//将螺旋矩阵按行输出 107 { 108 for(j=0;j<C2;j++) 109 printf("%c",a[i][j]); 110 //printf("\n");测试输出 111 } 112 } 113 114 return 0; 115 }
折腾好长时间,同时输入整数和字符串确实有点蛋疼。请注意代码中输入的方式。
另外,螺旋矩阵的旋转遍历也是重点。
最后,要特殊考虑只有一行、一列或者只剩下一行、一列的情况。这个时候要特殊处理。
其他的解题方式也很有参考价值:http://blog.csdn.net/zhengyuan233/article/details/53161002
时间: 2024-11-05 13:49:20