随手练——“打印”各种图形(宏观调度问题)

  • 将矩阵(二维数组)旋转90°

如果只是要求旋转后输出,非常简单:

#include <iostream>
using namespace std;

int f[100][100];

int main() {
    int n, count = 1;
    cin >> n;
    printf("原矩阵:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            f[i][j] = count++;
            printf("%4d",f[i][j]);
        }
        printf("\n");
    }
    printf("旋转之后:\n");
    for (int j = 0; j < n; j++) {
        for (int i = n - 1; i >= 0; i--) {
            printf("%4d", f[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 如果要求存回去,再开个数组倒腾一下就好。

但如果要求空间复杂度O(1),就得这样做了:

#include <iostream>
using namespace std;

int f[100][100];
void print(int p0,int p1) {
    if (p0 >= p1) {
        return;
    }
    for (int i = p0; i < p1; i++) {
        int t = f[p0][i];
        f[p0][i] = f[p1 - i][p0];
        f[p1 - i][p0] = f[p1][p1 - i];
        f[p1][p1 - i] = f[p0 + i][p1];
        f[p0 + i][p1] = t;
    }
    print(p0 + 1, p1 - 1);
}
int main() {
    int n, count = 1;
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            f[i][j] = count++;
        }
    }
        print(0,n-1);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%4d", f[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 

  • 正方形、长方形矩阵

给定左上角、右下角坐标,作为基准,给全局数组赋值。

因为是正方形矩阵,对角线上,横纵坐标是一样的,给两个数就够了。

#include <stdio.h>

int f[10][10];

void print(int p0,int p1) {
    static int count = 1;
    if (p0 >= p1) {
        if (p0 == p1)
        f[p0][p1] = count;
        return;
    }
    for (int i = p0; i <= p1; i++)f[p0][i] = count++;
    for (int i = p0 + 1; i <= p1; i++)f[i][p1] = count++;
    for (int i = p1 - 1; i >= p0; i--)f[p1][i] = count++;
    for (int i = p1 - 1; i > p0; i--)f[i][p0] = count++;
    print(p0 + 1, p1 - 1);
}
int main() {
    int n;
    scanf("%d",&n);
    print(0, n - 1);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%4d",f[i][j]);
        }
        printf("\n");
    }
    return 0;
}

方法和正方形几乎一致:

#include <stdio.h>

int f[100][100];

void print(int x0,int y0,int x1,int y1) {
    static int count = 1;
    if (x0 >= x1 || y0 >= y1) {
        if (x0 == x1) {
            for (int i = y0; i <= y1; i++)f[x0][i] = count++;
        }
        else {
            for (int i = x0; i <= x1; i++)f[i][y0] = count++;
        }
        return;
    }
    for (int i = y0; i <= y1; i++)f[x0][i] = count++;
    for (int i = x0 + 1; i <= x1; i++)f[i][y1] = count++;
    for (int i = y1 - 1; i >= y0; i--)f[x1][i] = count++;
    for (int i = x1 - 1; i > x0; i--)f[i][y0] = count++;
    print(x0 + 1, y0 + 1, x1 - 1, y1 - 1);
}
int main() {
    //m行,n列
    int m,n;
    scanf("%d%d",&m,&n);
    print(0, 0, m - 1, n - 1);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            printf("%4d",f[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 

从左上角开始,打印到右下角(按数据在线中的位置从左往右输出,每条对角线占一行)。

 

主要是一种思想,这个题如果想着,怎么转换输出形式能够输出成这样,就太难了。

我们就解决 给定左下,右上两个点 输出 一条线 ,后面就好做了。

#include <iostream>
using namespace std;

int f[100][100];
void print(int lx,int ly,int rx,int ry) {    
    while (lx >= rx) {
        printf("%4d", f[lx--][ly++]);
    }
    printf("\n");
}
int main() {
    int m, n, count = 1;
    //m行n列
    cin >> m >> n;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            f[i][j] = count++;
        }
    }
    int ax = 0, ay = 0, bx = 0, by = 0;
    //以ax,ay为例,起初ax每次+1,ay不变,当ax到最后一行,ax就不变了,ay开始+1
    while (ay != n) {
        print(ax,ay,bx,by);
        //要先给ay赋值,先写ax拐角处就不做了
        ay = ax == m - 1 ? ay + 1 : ay;
        ax = ax == m - 1 ? ax : ax + 1;

        bx = by == n - 1 ? bx + 1 : bx;
        by = by == n - 1 ? by : by + 1;
    }
    
    return 0;
}

 

posted @ 2019-02-01 16:03  czc1999  阅读(90)  评论(0编辑  收藏  举报