2023蓝桥杯 java A组 第四题棋盘
【问题描述】
小蓝拥有n×n大小的棋盘,一开始棋盘上全都是白子。小蓝进行了m次
操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋
子变为黑色,黑色棋子变为白色)。请输出所有操作做完后棋盘上每个棋子的颜
色。
【输入格式】
输入的第一行包含两个整数n,m,用一个空格分隔,表示棋盘大小与操作
数。
接下来m行每行包含四个整数x1,y1,x2,y2,相邻整数之间使用一个空格分
隔,表示将在x1至x2行和y1至y2列中的棋子颜色取反。
【输出格式】
输出n行,每行n个0或1表示该位置棋子的颜色。如果是白色则输出0
,否则输出1。
【样例输入】
3 3
1 1 2 2
2 2 3 3
1 1 3 3
【样例输出】
0 0 1
0 1 0
1 0 0
暴力解法(只能过去一部分数据)
static int[][] arr=new int[501][501];
public static void main(String[] args) {
int n,m,x1,x2,y1,y2;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
while((m--)!=0) {
x1=sc.nextInt();
y1=sc.nextInt();
x2=sc.nextInt();
y2=sc.nextInt();
for(int i=x1;i<=x2;i++) {
for(int j=y1;j<=y2;j++) {
arr[i-1][j-1]=1-arr[i-1][j-1];
}
}
}
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
差分法
static int[][] arr=new int[505][505];
public static void main(String[] args) {
int n,m,x1,y1,x2,y2;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
while(m--!=0) {
x1=sc.nextInt();
y1=sc.nextInt();
x2=sc.nextInt();
y2=sc.nextInt();
for(int i=x1;i<=x2;i++) {
arr[i][y1]++;
arr[i][y2+1]--;
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
arr[i][j]+=arr[i][j-1];
System.out.print(arr[i][j]%2);
}
System.out.println();
}
}
差分法分析:
在上例中,输入三行过程中,棋盘得变化如下:

输出结果时,当在一行中从左向右遍历时,存在arr[i][j]+=arr[i][j-1];
以下可以通过①去看下面解释
(1)当arr[i][j]和arr[i][j-1]在一个矩形中,它们改变得次数相同,那么只有左侧arr[i][j-1]记录了改变得次数,arr[i][j]没记录,arr[i][j]+=arr[i][j-1]; 就可以使arr[i][j]得到它总的改变次数,当这个数是偶数时,就颜色不变,否则,变为相反色。
(2)当arr[i][j]刚好是改变了的矩形得下一列时,由于arr[i][y2+1]--;和arr[i][j]+=arr[i][j-1]; 可以使得这个格子没有发生改变。
大规模数据时,这个方法得效率很高

浙公网安备 33010602011771号