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]; 可以使得这个格子没有发生改变。

大规模数据时,这个方法得效率很高

posted @ 2024-04-11 16:57  skiesclear  阅读(59)  评论(0)    收藏  举报