反反复复

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

先还原蛇形读取的行方向,再按列从上到下读取矩阵恢复原始信息。

OJ: noi_openjudge

题目 ID: ch0108-20

难度:普及-

标签:矩阵字符串模拟python

日期: 2026-07-30 23:01

题意

给定蛇形逐行读出的密文和列数,恢复原始按列从上到下填入的字符串。

思路

密文每 column_count 个字符是一行;偶数编号行在加密时从右向左读取,需要先反转回来。恢复所有正常行后,按列从左到右、每列从上到下读取,就是原始填入顺序。

代码

cpp
#include <cstdio>
#include <cstring>


int n;
int line;
char a[400][400];
char str[100000];

void xchg(char &i,char &j){
    char t = i;
    i = j;
    j = t;
}

void rev(char s[]){
    int i;
    for (i=1;i<=n/2;i++){
        xchg(s[i], s[n-i+1]);
    }
}

void init(){
    scanf("%d",&n);
    scanf("%s",str+1);
    int i,j;
    int len = strlen(str+1);
    line = len / n;
    for (i=1;i<=line;i++){
        for (j=1;j<=n;j++){
            a[i][j] = str[(i-1)*n+j];
        }
    }
    for (i=1;i<=line;i++){
        if( i % 2 == 0)
            rev(a[i]);
    }

    /*
     *for (i=1;i<=line;i++){
     *    for (j=1;j<=n;j++){
     *        printf("%c ",a[i][j]);
     *    }
     *    printf("\n");
     *}
     */

}
int main(){
    init();
    int i,j;
    for (j=1;j<=n;j++){
        for (i=1;i<=line;i++){
            printf("%c",a[i][j]);
        }
    }
    return 0;
}

复杂度

总结

Python代码

python
column_count = int(input())
ciphertext = input().strip()
row_count = len(ciphertext) // column_count
rows = []

for row in range(row_count):
    segment = ciphertext[row * column_count : (row + 1) * column_count]
    rows.append(segment if row % 2 == 0 else segment[::-1])

print("".join(rows[row][column] for column in range(column_count) for row in range(row_count)))

C++代码

cpp
#include <cstdio>
#include <cstring>


int n;
int line;
char a[400][400];
char str[100000];

void xchg(char &i,char &j){
    char t = i;
    i = j;
    j = t;
}

void rev(char s[]){
    int i;
    for (i=1;i<=n/2;i++){
        xchg(s[i], s[n-i+1]);
    }
}

void init(){
    scanf("%d",&n);
    scanf("%s",str+1);
    int i,j;
    int len = strlen(str+1);
    line = len / n;
    for (i=1;i<=line;i++){
        for (j=1;j<=n;j++){
            a[i][j] = str[(i-1)*n+j];
        }
    }
    for (i=1;i<=line;i++){
        if( i % 2 == 0)
            rev(a[i]);
    }

    /*
     *for (i=1;i<=line;i++){
     *    for (j=1;j<=n;j++){
     *        printf("%c ",a[i][j]);
     *    }
     *    printf("\n");
     *}
     */

}
int main(){
    init();
    int i,j;
    for (j=1;j<=n;j++){
        for (i=1;i<=line;i++){
            printf("%c",a[i][j]);
        }
    }
    return 0;
}

复杂度

设密文长度为 LL,时间和额外空间复杂度均为 O(L)O(L)

总结

蛇形编码的解码通常先还原每行方向,再按原填充方向遍历。