图像旋转翻转变换

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

按操作顺序用转置、切片和行逆序模拟图像旋转与翻转。

OJ: noi_openjudge

题目 ID: ch0112-09

难度:普及-

标签:矩阵模拟python

日期: 2026-07-30 23:01

题意

对灰度矩阵依次执行顺时针旋转、逆时针旋转、左右翻转或上下翻转,输出最终图像。

思路

顺时针旋转可写为“先逆序行,再转置”:zip(*image[::-1])。逆时针旋转为先转置再逆序行。左右翻转是每行 [::-1],上下翻转是行列表 [::-1]。操作必须按给定字符串顺序执行。

代码

Python代码

python
row_count, column_count = map(int, input().split())
image = [input().split() for _ in range(row_count)]
operations = input()

for operation in operations:
    if operation == "A":
        image = [list(row) for row in zip(*image[::-1])]
    elif operation == "B":
        image = [list(row) for row in zip(*image)][::-1]
    elif operation == "C":
        image = [row[::-1] for row in image]
    else:
        image = image[::-1]

for row in image:
    print(*row)

C++代码

cpp
#include <cstdio>
#include <cstring>

int map[200][200];
int map_bak[200][200];
char str[1000];
int m,n;

void _swap(int &a,int &b){
    int t = a; a = b; b = t;
}

void clock(){
    int i,j;
    for(i=1;i<=m;i++)
        for(j=1;j<=n;j++){
            map_bak[j][m-i+1]= map[i][j];
        }
    memcpy(map,map_bak,sizeof(map));
    _swap(n,m);
}
void anti_clock(){
    int i,j;
    for(i=1;i<=m;i++)
        for(j=1;j<=n;j++){
             map_bak[n-j+1][i]= map[i][j];
        }
    memcpy(map,map_bak,sizeof(map));
    _swap(n,m);
}

void left_right(){
    int i,j;
    for (i=1;i<=m;i++){
        for (j=1;j<=n;j++){
            map_bak[i][n-j+1]= map[i][j];
        }
    }
    memcpy(map,map_bak,sizeof(map));
}

void up_down(){
    int i,j;
    for (i=1;i<=m;i++){
        for (j=1;j<=n;j++){
            map_bak[m-i+1][j]= map[i][j];
        }
    }
    memcpy(map,map_bak,sizeof(map));
}
int main(){
    scanf("%d%d",&m,&n);
    int i,j;
    for (i=1;i<=m;i++){
        for (j=1;j<=n;j++){
            scanf("%d",&map[i][j]);
        }
    }
    scanf("%s",str);
    int len  = strlen(str);
    for (i=0;i<len;i++){
        char c = str[i];
        if( c == 'A')
            clock();
        else if( c == 'B')
            anti_clock();
        else if( c == 'C')
            left_right();
        else if( c == 'D')
            up_down();
    }
    for (i=1;i<=m;i++){
        for (j=1;j<=n;j++){
            printf("%d ",map[i][j]);
        }
        printf("\n");
    }
    return 0;
}

复杂度

设操作数为 qq,时间复杂度为 O(qmn)O(qmn),空间复杂度为 O(mn)O(mn)

总结

矩阵变换的关键是每一步都使用当前矩阵,旋转后行列数会交换。