螺旋加密

GitHub跳转原题关系图返回列表

将字符转为五位二进制流,按顺时针螺旋写入矩阵后按行输出密文。

OJ: noi_openjudge

题目 ID: ch0108-25

难度:普及-

标签:矩阵字符串模拟编码python

日期: 2026-07-30 23:01

题意

把空格和大写字母编码为五位二进制数,按顺时针螺旋填入矩阵,最后按行输出二进制密文。

思路

空格映射为 00,字母映射为 112626f"{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;
}

复杂度

设矩阵容量为 RCRC,时间和空间复杂度均为 O(RC)O(RC)

总结

螺旋加密由“字符到位流”和“位流到矩阵路径”两个独立步骤组成。