首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

矩陣區域旋轉問題:北郵上機題 C 語言完整解法與幾何變換解析

     編輯:關於C語言

題目重述

  • 輸入 5×5 整數矩陣
  • 輸入操作碼 t1 t2 x y:
    • t1=1 順時針,t1=2 逆時針
    • t2=2 2×2 區域,t2=3 3×3 區域
    • (x,y) 為區域左上角座標(1-based)
  • 輸出旋轉後完整矩陣

幾何變換數學基礎

以區域左上角為原點 (0,0),區域大小 N×N(N=2 或 3)。

順時針 90°:(r, c) → (c, N-1-r)

逆時針 90°:(r, c) → (N-1-c, r)

映射回全域矩陣座標:

/* 區域內相對座標 */
int rr = i - x, cc = j - y;  // 0-based 相對座標

/* 順時針 */
new_r = x + cc;
new_c = y + (N - 1 - rr);

/* 逆時針 */
new_r = x + (N - 1 - cc);
new_c = y + rr;

完整 C 解法(AC 代碼)

#include <stdio.h>
#include <stdlib.h>

void rotate_submatrix(int src[5][5], int dst[5][5], 
                      int x, int y, int N, int clockwise) {
    /* 先整體複製 */
    for (int i = 0; i < 5; i++)
        for (int j = 0; j < 5; j++)
            dst[i][j] = src[i][j];

    /* 僅修改區域內元素 */
    for (int i = x; i < x + N; i++) {
        for (int j = y; j < y + N; j++) {
            int rr = i - x, cc = j - y;
            int ni, nj;
            if (clockwise) {
                ni = x + cc;
                nj = y + (N - 1 - rr);
            } else {
                ni = x + (N - 1 - cc);
                nj = y + rr;
            }
            dst[ni][nj] = src[i][j];
        }
    }
}

int main() {
    int a[5][5], b[5][5];
    int t1, t2, x, y;
    
    while (1) {
        /* 讀取矩陣 */
        if (scanf("%d", &a[0][0]) != 1) break;  // EOF
        for (int i = 0; i < 5; i++)
            for (int j = 0; j < 5; j++)
                if (!(i == 0 && j == 0)) scanf("%d", &a[i][j]);
        
        /* 讀取操作參數 */
        scanf("%d %d %d %d", &t1, &t2, &x, &y);
        x--; y--;  // 轉 0-based
        
        int N = t2;  // 2 或 3
        int cw = (t1 == 1);
        
        rotate_submatrix(a, b, x, y, N, cw);
        
        /* 輸出 */
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                printf("%d%c", b[i][j], j == 4 ? '\n' : ' ');
            }
        }
    }
    return 0;
}

樣例驗證

輸入:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
1 3 1 1

對應: t1=1(順), t2=3(3x3), x=1,y=1 → 左上角 (0,0) 3x3 區域順時針

輸出:
11 6 1 4 5
12 7 2 9 10
13 8 3 14 15
16 17 18 19 20
21 22 23 24 25

關鍵測試點

  • 邊界:x=4,y=4,N=2 超出矩陣(題目保證合法)
  • 多組測試資料:while(scanf(...)) 正確處理 EOF
  • 輸出格式:每行末尾無多餘空格,行間換行
  • 原矩陣不修改:使用 dst 緩衝區

擴展:通用 N×N 矩陣任意 K×K 區域旋轉

void rotate_kxk(int n, int src[n][n], int dst[n][n], 
                int x, int y, int k, int cw) {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            dst[i][j] = src[i][j];
    
    for (int i = x; i < x + k; i++)
        for (int j = y; j < y + k; j++) {
            int rr = i - x, cc = j - y;
            int ni = cw ? x + cc : x + (k - 1 - cc);
            int nj = cw ? y + (k - 1 - rr) : y + rr;
            dst[ni][nj] = src[i][j];
        }
}

複雜度分析

  • 時間:O(5²) = O(1) —— 固定 5×5,常數時間
  • 空間:O(5²) = O(1) —— 兩個 5×5 緩衝區
  • 若推廣至 N×N:時間 O(N²),空間 O(N²)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved