将字符转为五位二进制流,按顺时针螺旋写入矩阵后按行输出密文。
OJ: noi_openjudge
题目 ID: ch0108-25
难度:普及-
标签:矩阵字符串模拟编码python
日期: 2026-07-30 23:01
题意
把空格和大写字母编码为五位二进制数,按顺时针螺旋填入矩阵,最后按行输出二进制密文。
思路
空格映射为 f"{value:05b}" 生成五位二进制。将不足矩阵容量的位补零后,用四边界螺旋路径写入,最后按行拼接。
代码
cpp
#include <cstdio>
int n,m,a[1010][1010] = {0};
int seq[10000];
int cnt =0;
void push_bin_2_seq(int x){
int i;
//printf("%d\n",x);
for(i=4;i>=0;i--){
if( x & ( 1 << i))
seq[cnt] = 1;
else
seq[cnt] = 0;
cnt++;
}
}
void init(){
scanf("%d%d",&n,&m);
int i,j;
char t;
scanf("%c",&t); // 略过空格
while( scanf("%c",&t) != EOF){
if( t == '\n' || t == '\r') break;
int ret;
if( t==' ')
ret = 0;
else
ret = t-'A'+1;
push_bin_2_seq(ret);
}
}
int main(){
init();
int idx = 0;
int i,j; int r1=1,r2=n,c1=1,c2=m;
while( r1 <= r2 && c1 <= c2 && idx < cnt){
for(j=c1;j<=c2;j++)
a[r1][j] = seq[idx++];
for(i=r1+1;i<=r2;i++)
a[i][c2] = seq[idx++];
if( r1 != r2)
for(j = c2-1;j>=c1;j--)
a[r2][j] = seq[idx++];
if(c1!=c2)
for(int i=r2-1;i>r1;i--)
a[i][c1] = seq[idx++];
r1++;
r2--;
c1++;
c2--;
}
for(i=1;i<=n;i++){
for (j=1;j<=m;j++){
printf("%d",a[i][j]);
}
}
return 0;
}复杂度
总结
Python代码
python
row_text, column_text, message = input().split(" ", 2)
row_count = int(row_text)
column_count = int(column_text)
bits = "".join(f"{0 if character == ' ' else ord(character) - ord('A') + 1:05b}" for character in message)
bits += "0" * (row_count * column_count - len(bits))
matrix = [["0"] * column_count for _ in range(row_count)]
index = 0
top, bottom = 0, row_count - 1
left, right = 0, column_count - 1
while top <= bottom and left <= right:
for column in range(left, right + 1):
matrix[top][column] = bits[index]
index += 1
for row in range(top + 1, bottom + 1):
matrix[row][right] = bits[index]
index += 1
if top < bottom:
for column in range(right - 1, left - 1, -1):
matrix[bottom][column] = bits[index]
index += 1
if left < right:
for row in range(bottom - 1, top, -1):
matrix[row][left] = bits[index]
index += 1
top, bottom = top + 1, bottom - 1
left, right = left + 1, right - 1
print("".join("".join(row) for row in matrix))C++代码
cpp
#include <cstdio>
int n,m,a[1010][1010] = {0};
int seq[10000];
int cnt =0;
void push_bin_2_seq(int x){
int i;
//printf("%d\n",x);
for(i=4;i>=0;i--){
if( x & ( 1 << i))
seq[cnt] = 1;
else
seq[cnt] = 0;
cnt++;
}
}
void init(){
scanf("%d%d",&n,&m);
int i,j;
char t;
scanf("%c",&t); // 略过空格
while( scanf("%c",&t) != EOF){
if( t == '\n' || t == '\r') break;
int ret;
if( t==' ')
ret = 0;
else
ret = t-'A'+1;
push_bin_2_seq(ret);
}
}
int main(){
init();
int idx = 0;
int i,j; int r1=1,r2=n,c1=1,c2=m;
while( r1 <= r2 && c1 <= c2 && idx < cnt){
for(j=c1;j<=c2;j++)
a[r1][j] = seq[idx++];
for(i=r1+1;i<=r2;i++)
a[i][c2] = seq[idx++];
if( r1 != r2)
for(j = c2-1;j>=c1;j--)
a[r2][j] = seq[idx++];
if(c1!=c2)
for(int i=r2-1;i>r1;i--)
a[i][c1] = seq[idx++];
r1++;
r2--;
c1++;
c2--;
}
for(i=1;i<=n;i++){
for (j=1;j<=m;j++){
printf("%d",a[i][j]);
}
}
return 0;
}复杂度
设矩阵容量为
总结
螺旋加密由“字符到位流”和“位流到矩阵路径”两个独立步骤组成。