代码改错:c/java同一思路

C/Java
想知道错在哪

img

1.c二维数组在vs上开到10010x10010(题目要求),在定义时报栈溢出错误,以前貌似是可以开到这么大的

img

2.当我缩小到100x100,仍不能完全通过,到底是错哪里呀??


#include
int main() {
    int n, m, q;
    scanf_s("%d %d %d", &n, &m, &q);
    int a[100][100] = { 0 };
    for (int i = 0; i < q; i++) {
        int t,c;
        scanf_s("%d %d", &t, &c);
        if (t == 0) {
            for (int j = 0; j < m; j++) {
                a[c][j] = 1;
            }
        }
        if (t == 1) {
            for (int j = 0; j < n; j++) {
                a[j][c] = 1;
            }
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == 0) {
                cnt++;
            }
        }
    }
    printf("%d", cnt);
    return 0;
}

img

3.用java写,经常报“非零返回错误”,这段代码又有什么问题呀,同c的思路是一样的

import java.util.Scanner;
public class Main {
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in=new Scanner(System.in);
        int n,m,q;
        n=in.nextInt();
        m=in.nextInt();
        q=in.nextInt();
        int [][]arr=new int [n][m];
        for(int i=0;iint t=in.nextInt();
            int c=in.nextInt();
            if(t==0) {
                for(int j=0;j1;
                }
            }
            if(t==1) {
                for(int j=0;j1;
                }
            }
        }
        int cnt=0;
        for(int i=0;ifor(int j=0;jif(arr[i][j]==0) {
                    cnt++;
                }
            }
        }
        System.out.println(cnt);
    }
}

运行结果:

img

题目是10的5次方,你最多才开10的4次方。把int a【100010】【100010】放在外面,就是开在堆区。其实这没必要开这么大数组来模拟,完全可以计算出来,参考下面的代码,下面的代码考虑的是行列不被多次选中的情况,你可以提交试试看

该回答引用于gpt与OKX安生共同编写:
  • 该回答引用于gpt与OKX安生共同编写:

根据您提供的信息和代码截图,我看到了以下问题:

  • 在 C 语言中,使用 scanf_s 函数时需要同时指定输入缓冲区大小。例如,将 scanf_s("%d %d %d", &n, &m, &q); 改为 scanf_s("%d %d %d", &n, &m, &q,(unsigned)_msize(a));。这是因为 scanf_s 函数属于安全函数族,它要求程序员在编写代码时必须考虑输入数据的长度和格式,以避免缓冲区溢出等安全问题。
  • 在 C 语言中,栈空间有限,无法直接创建如此大的二维数组。如果需要创建较大的数组,可以考虑使用动态内存分配方式,例如使用 malloc 或者 calloc 函数来分配堆空间。例如,可以将 int a[100][100] = { 0 }; 改为 int** a = (int**)malloc(sizeof(int*)*n); for (int i = 0; i < n; ++i) a[i] = (int*)calloc(m, sizeof(int));
  • 在 Java 中,运行结果显示了“非零返回错误”的信息,这可能是因为代码存在逻辑上的错误导致运行异常。检查代码后发现,在处理输入数据时,第一行应该先输入 n、m 和 q,然后再定义二维数组,否则数组大小不正确,会导致越界等异常。因此,需要将两部分代码互换位置,即将 int [][]arr=new int [n][m]; 的定义放在读入 n、m 和 q 的前面。
  • 修改后的 C 语言代码如下所示:
#include<stdio.h>
#include<stdlib.h>
int main() {
    int n, m, q;
    scanf_s("%d %d %d", &n, &m, &q, (unsigned)_msize(a));
    int** a = (int**)malloc(sizeof(int*) * n);
    for (int i = 0; i < n; ++i)
        a[i] = (int*)calloc(m, sizeof(int));
    for (int i = 0; i < q; i++) {
        int t, c;
        scanf_s("%d %d", &t, &c);
        if (t == 0) {
            for (int j = 0; j < m; j++) {
                a[c][j] = 1;
            }
        }
        if (t == 1) {
            for (int j = 0; j < n; j++) {
                a[j][c] = 1;
            }
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == 0) {
                cnt++;
            }
        }
    }
    printf("%d", cnt);
    return 0;
}
  • 修改后的 Java 代码如下所示:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n, m, q;
        n = in.nextInt();
        m = in.nextInt();
        q = in.nextInt();
        int[][] arr = new int[n][m];
        for (int i = 0; i < q; i++) { // q 行数据
            int t = in.nextInt();
            int c = in.nextInt();
            if (t == 0) {
                for (int j = 0; j < m; j++) {
                    arr[c][j] = 1;
                }
            }
            if (t == 1) {
                for (int j = 0; j < n; j++) {
                    arr[j][c] = 1;
                }
            }
        }
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (arr[i][j] == 0) {
                    cnt++;
                }
            }
        }
        System.out.println(cnt);
    }
}

参考GPT和自己的思路,在比较 C 语言代码和Java代码之后,我注意到Java代码在使用Scanner读取输入时,调用的是nextInt()方法,但 C 语言代码使用的是scanf_s()函数。由于Java代码中没有scanf_s()函数,而应该使用Scanner中的nextLine()方法来替代,这将读取一行输入,并使用split()函数将输入分解为整数。此外,由于Java代码中的数组大小被声明为[n][m],而不是[100][100],因此需要确保输入的n和m值不超过数组大小。

下面是修改后的Java代码:

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
      Scanner in = new Scanner(System.in);
      int n, m, q;
      n = in.nextInt();
      m = in.nextInt();
      q = in.nextInt();
      int[][] arr = new int[n][m];
      in.nextLine(); // consume the endline after the third integer input
      for (int i = 0; i < q; i++) {
          String[] line = in.nextLine().split(" ");
          int t = Integer.parseInt(line[0]);
          int c = Integer.parseInt(line[1]);
          if (t == 0) {
              for (int j = 0; j < m; j++) {
                  arr[c][j] = 1;
              }
          }
          if (t == 1) {
              for (int j = 0; j < n; j++) {
                  arr[j][c] = 1;
              }
          }
      }
      int cnt = 0;
      for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
              if (arr[i][j] == 0) {
                  cnt++;
              }
          }
      }
      System.out.println(cnt);
  }
}

该回答引用ChatGPT

如有疑问,可以回复我!

还请测试
C语言代码如下

#include <stdio.h>
#include <stdbool.h>

int main() {
    int n, m, q, i, t, c, safeCount;
    scanf("%d%d%d", &n, &m, &q);
    
    bool row[n], col[m];
    
    for (i = 0; i < n; i++) {
        row[i] = false;
    }
    
    for (i = 0; i < m; i++) {
        col[i] = false;
    }
    
    for (i = 0; i < q; i++) {
        scanf("%d%d", &t, &c);
        if (t == 0) {
            row[c - 1] = true;
        } else {
            col[c - 1] = true;
        }
    }
    
    safeCount = 0;
    for (i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (!row[i] && !col[j]) {
                safeCount++;
            }
        }
    }
    
    printf("%d\n", safeCount);
    
    return 0;
}


JAVA 代码如下

import java.util.Scanner;

public class SafeGrid {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int q = sc.nextInt();
        
        boolean[] row = new boolean[n];
        boolean[] col = new boolean[m];
        
        for (int i = 0; i < q; i++) {
            int t = sc.nextInt();
            int c = sc.nextInt();
            if (t == 0) {
                row[c - 1] = true;
            } else {
                col[c - 1] = true;
            }
        }
        
        int safeCount = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!row[i] && !col[j]) {
                    safeCount++;
                }
            }
        }
        
        System.out.println(safeCount);
    }
}


参考GPT和自己的思路:
1 C代码报栈溢出错误是因为你在栈空间上创建了一个过大的数组,导致栈溢出。可以将数组改为动态分配的方式,使用malloc函数在堆上创建数组。例如:

int** a = (int**)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++) {
    a[i] = (int*)malloc(m * sizeof(int));
}


2 C代码中,你定义的数组大小只有100x100,如果要支持10010x10010的情况,需要使用动态分配的方式创建数组。另外,如果缩小到100x100仍然无法通过,可能是其他原因导致的错误,需要更多的信息来确定。

3 Java代码中,你定义的数组大小只有n x m,如果要支持10010x10010的情况,也需要使用动态分配的方式创建数组。另外,“非零返回错误”通常是因为程序在某些情况下返回了非0的错误码,需要检查代码中的逻辑是否正确。

该回答引用GPTᴼᴾᴱᴺᴬᴵC语言代码中,栈溢出的问题是因为定义的二维数组太大,可以使用动态内存分配来解决,例如:

int **a;
a = (int **)malloc(n * sizeof(int *));
for (int i = 0; i < n; i++) {
    a[i] = (int *)malloc(m * sizeof(int));
}

另外,题目中给定的地图大小为N × M,因此二维数组的定义应为 int a[10010][10010],而不是 int a[100][100]。

Java代码中的问题是变量名错误,第二个整数应该是j而不是c,即应为 int j=in.nextInt();。

正确的C代码如下:

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

int main() {
    int n, m, q;
    scanf("%d %d %d", &n, &m, &q);
    int **a;
    a = (int **)malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        a[i] = (int *)malloc(m * sizeof(int));
    }
    for (int i = 0; i < q; i++) {
        int t, c;
        scanf("%d %d", &t, &c);
        if (t == 0) {
            for (int j = 0; j < m; j++) {
                a[c][j] = 1;
            }
        }
        if (t == 1) {
            for (int j = 0; j < n; j++) {
                a[j][c] = 1;
            }
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == 0) {
                cnt++;
            }
        }
    }
    printf("%d\n", cnt);
    return 0;
}

正确的Java代码如下:

import java.util.Scanner;

public class Main {
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n, m, q;
        n = in.nextInt();
        m = in.nextInt();
        q = in.nextInt();
        int[][] a = new int[n][m];
        for (int i = 0; i < q; i++) {
            int t = in.nextInt();
            int j = in.nextInt();
            if (t == 0) {
                for (int k = 0; k < m; k++) {
                    a[j][k] = 1;
                }
            }
            if (t == 1) {
                for (int k = 0; k < n; k++) {
                    a[k][j] = 1;
                }
            }
        }
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (a[i][j] == 0) {
                    cnt++;
                }
            }
        }
        System.out.println(cnt);
    }
}

安全数=n✘m-n✘c0个数-m✘c1个数+c0个数✘c1个数
例如 n=5 m=8 q=3,2个 c0 1个c1
r=5✘8-5✘2-8✘1+2✘1=24

我的思路和满意回答的一样,不用二维数组,记录boss在几行几列放了技能,放过技能的行数乘M,加放过技能的列数乘N,再减去重复的格子数就是boss技能覆盖的格子数。重复的格子数,就等于放过技能的行数乘放过技能的列数。不过我的代码考虑了boss在同一行或同一列放技能的情况。

#include<stdio.h>

char a[2][100000]={0};

int main(){
    int i,n,m,q,j,k,c[2]={0};
    scanf("%d%d%d",&n,&m,&q);
    for(i=0;i<q;i++){
        scanf("%d%d",&j,&k);
        if(a[j][k]==0)c[j]++;
        a[j][k]=1;
    }
    printf("%d",m*n-c[0]*m-c[1]*n+c[0]*c[1]);
    return 0;
}

img

这个题推荐一下我的博客,或许可以开拓一下你的思路,二维数组是不可以开这么大的,如果你需要用到这么大的了,那说明你的算法需要改进,有什么问题可以在我的博客下留言

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
C代码中的问题:

  1. C语言中数组的定义是存储在栈中的,而栈的大小是有限制的,因此开到10010x10010的二维数组会报栈溢出错误。可以使用动态内存分配方式malloc实现动态分配空间,这样可以避免栈溢出错误。

  2. 在缩小为100x100后,还有可能是由于数组越界导致的,例如输入的t或c可能超过了数组的范围,需要确保t和c的值在[0,n)和[0,m)之间,否则会出现越界的错误。

C语言代码改正后的结果如下:

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

int main() {
    int n, m, q;
    scanf("%d %d %d", &n, &m, &q);
    int **a = (int **)malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        a[i] = (int *)malloc(m * sizeof(int));
        for (int j = 0; j < m; j++) {
            a[i][j] = 0;
        }
    }
    for (int i = 0; i < q; i++) {
        int t, c;
        scanf("%d %d", &t, &c);
        if (t == 0) {
            for (int j = 0; j < m; j++) {
                a[c][j] = 1;
            }
        }
        if (t == 1) {
            for (int j = 0; j < n; j++) {
                a[j][c] = 1;
            }
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == 0) {
                cnt++;
            }
        }
    }
    printf("%d", cnt);
    for (int i = 0; i < n; i++) {
        free(a[i]);
    }
    free(a);
    return 0;
}

Java代码中的问题:
该Java代码没有明显错误,但是部分在线评测系统要求主方法的返回值必须是0,如果返回值是其他整数可能会报“非零返回错误”的错误。需要在主方法的末尾添加“return 0;”语句。

Java语言代码改正后的结果如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n, m, q;
        n = in.nextInt();
        m = in.nextInt();
        q = in.nextInt();
        int[][] arr = new int[n][m];
        for (int i = 0; i < q; i++) {
            int t = in.nextInt();
            int c = in.nextInt();
            if (t == 0) {
                for (int j = 0; j < m; j++) {
                    arr[c][j] = 1;
                }
            }
            if (t == 1) {
                for (int j = 0; j < n; j++) {
                    arr[j][c] = 1;
                }
            }
        }
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (arr[i][j] == 0) {
                    cnt++;
                }
            }
        }
        System.out.println(cnt);
        return 0;
    }
}

如果我的回答解决了您的问题,请采纳!