今天做一题感觉递归出错了 但是又感觉没错

题目描述
现有 2^n * 2^(n≤10) 名作弊者站成一个正方形方阵等候你的发落。 你决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。
给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。
输入格式
一个整数 n。
输出格式
2^n * 2^n的 01 矩阵,代表每个人是否被赦免。数字之间有一个空格。
输入输出样例
3
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 0 1
0 0 0 0 1 1 1 1
0 0 0 1 0 0 0 1
0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1

#include<stdio.h>
int calculate(int n);
void draw(int a[][256], int length, int n, int imax, int imin, int jmax, int jmin);
int main(void)
{
    int n, length, i, j;
    int imax, imin, jmax, jmin;
    int a[256][256];

    scanf_s("%d", &n);
    length = calculate(n);
    for (i = 0; i < length; i++)
        for (j = 0; j < length; j++)
            a[i][j] = 1;
    imax = jmax = length;
    imin = jmin = 1;
    draw(a, length, n, imax, imin, jmax, jmin);
    for (i = 0; i < length; i++)
    {
        for (j = 0; j < length; j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }
    return 0;
}

int calculate(int n)
{
    int i = 1;
    int answer = 1;

    for (i = 1; i <= n; i++)
    {
        answer *= 2;
    }

    return answer;
}

void draw(int a[][256], int length, int n, int imax, int imin, int jmax, int jmin)
{
    int i, j;
    if (n != 1)
    {
        for (i = imin; i <= imax / 2; i++)
            for (j = jmin; j <= jmax / 2; j++)
                a[i - 1][j - 1] = 0;//左上角那块
        draw(a, length, n - 1, imax, imax / 2, jmax / 2, jmin);//右上角那块
        draw(a, length, n - 1, imax / 2, imin, jmax, jmax / 2);//左下角那块
        draw(a, length, n - 1, imax, imax / 2, jmax, jmax / 2);//右下角那块
    }
    else
    {
        a[length - 2][length - 2] = 0;
    }
    return;
}

刚开始学C,做的最久的一题,硬是不知道错误出在哪里(cry

img

引用 皆我百晓生 小程序回复内容作答:

根据你提供的代码,我发现可能存在以下几个问题:

  1. 在函数draw中,递归调用时传递的参数imaxjmax应该是imax / 2jmax / 2,而不是imaxjmax。因为你要将矩阵分成四个更小的矩阵,所以需要将边界值缩小一半。

  2. 在函数draw中,递归调用时传递的参数iminjmin应该是jmax / 2 + 1imin,而不是iminjmin。因为你要将矩阵分成四个更小的矩阵,所以需要将边界值调整为正确的位置。

  3. 在函数draw中,递归调用时传递的参数imaxjmax应该是imax / 2jmax,而不是imaxjmax / 2。因为你要将矩阵分成四个更小的矩阵,所以需要将边界值缩小一半。

  4. 在函数draw中,递归调用时传递的参数imaxjmax应该是imaxjmax / 2,而不是imax / 2jmax / 2。因为你要将矩阵分成四个更小的矩阵,所以需要将边界值调整为正确的位置。

请根据上述修改建议进行代码调整,然后再次运行程序,看看是否能够得到正确的结果。如果还有其他问题,请随时提问。

【以下回答由 GPT 生成】

这段代码中存在一些小问题。我将在以下代码中进行说明和修复。

#include <stdio.h>

void draw(int a[][256], int length, int imax, int imin, int jmax, int jmin);

int main(void)
{
    int n, length, i, j;
    int imax, imin, jmax, jmin;
    int a[256][256];

    scanf("%d", &n);
    length = 1 << n; // 计算方阵的边长
    for (i = 0; i < length; i++)
        for (j = 0; j < length; j++)
            a[i][j] = 1;
    imax = jmax = length - 1; // 修复边界值错误
    imin = jmin = 0; // 修复边界值错误
    draw(a, length, imax, imin, jmax, jmin);
    for (i = 0; i < length; i++)
    {
        for (j = 0; j < length; j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }
    return 0;
}

void draw(int a[][256], int length, int imax, int imin, int jmax, int jmin)
{
    int i, j;
    if (length != 1) // 修复递归停止条件错误
    {
        int half = length / 2; // 计算每个子方阵的边长
        for (i = imin; i <= imin + half - 1; i++) // 修复边界值错误
            for (j = jmin; j <= jmin + half - 1; j++) // 修复边界值错误
                a[i][j] = 0;
        draw(a, half, imin, imin, jmin, jmin);
        draw(a, half, imax, imin, jmax, jmin + half);
        draw(a, half, imin + half, imin + half, jmin, jmin);
    }
}

希望这可以帮到你。如果你对代码有任何疑问,请随时提问。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^