专栏文章

B4229 棋盘 题解

B4229题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min1lbr5
此快照首次捕获于
2025/12/01 19:04
3 个月前
此快照最后确认于
2025/12/01 19:04
3 个月前
查看原文

1. 题意解释

给出一个 n×nn\times n 的黑白交替网格,每次对某一行或某一列做黑白翻转操作,求每次操作后的黑白格四连通块个数。

2. 思路

我们不难发现一开始的黑白网格可以看做是对全黑(或全白)图做奇数(或偶数)行列翻转得到。
我们考虑记录每行及每列的操作数。
考虑如何从行列中的操作数求出连通块个数。
不难发现每个连通块一定是呈方格状,且每个连通块一定对应一行上的连通块和一列上的连通块,所以我们只需要求出一行及一列的黑白连通块数,相乘即得到总的连通块数量。
对于一行(或一列)的连通块数,不难发现我们可以在每次操作时比较这一行(或这一列)操作的那个格子与其两边的格子颜色,然后就可以很简单的计算了。

3. 代码实现

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,op,a,row[100100],col[100100],rowcnt,colcnt;
signed main(){
    cin>>n;
    for(int i=2;i<=n;i+=2){
    	row[i]=col[i]=1;
	}
	cin>>q;
	rowcnt=colcnt=n;
	while(q--){
		cin>>op>>a;
		if(op==1){
			if(a==1){
				if(row[a]==row[a+1]){
					rowcnt=min(rowcnt+1,n);
				}
				else{
					rowcnt=max(rowcnt-1,1ll);
				}
				row[a]^=1;
			}
			else if(a==n){
				if(row[a]==row[a-1]){
					rowcnt=min(rowcnt+1,n);
				}
				else{
					rowcnt=max(rowcnt-1,1ll);
				}
				row[a]^=1;
			}
			else{
				if(row[a]==row[a+1]&&row[a]==row[a-1]){
					rowcnt=min(rowcnt+2,n);
				}
				else if(row[a]!=row[a+1]&&row[a]!=row[a-1]){
					rowcnt=max(rowcnt-2,1ll);
				}
				row[a]^=1;
			}
		}
		if(op==2){
			if(a==1){
				if(col[a]==col[a+1]){
					colcnt=min(colcnt+1,n);
				}
				else{
					colcnt=max(colcnt-1,1ll);
				}
				col[a]^=1;
			}
			else if(a==n){
				if(col[a]==col[a-1]){
					colcnt=min(colcnt+1,n);
				}
				else{
					colcnt=max(colcnt-1,1ll);
				}
				col[a]^=1;
			}
			else{
				if(col[a]==col[a+1]&&col[a]==col[a-1]){
					colcnt=min(colcnt+2,n);
				}
				else if(col[a]!=col[a+1]&&col[a]!=col[a-1]){
					colcnt=max(colcnt-2,1ll);
				}
				col[a]^=1;
			}
		}
		cout<<rowcnt*colcnt<<'\n';
	}
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...