CF1720C Corners 题解
赛时因为把
本题解题的关键点在于:如何让每次操作删除较少的
我们定义一片“空区”为两个相邻的
00
0
0
也有可能长这样(用 x 代表未知元素):
0
x0
如果是这样,我们每次就可以消去可以与它们构成“L 形”的某个
所以,如果整个矩阵刚开始存在空区,那么我们就可以让上面的操作一直执行下去,于是操作数就等于
但,如果刚开始的时候没有“空区”怎么办?
很显然,进行
我们可以推出,如果整个矩阵刚开始没有“空区”,就分两种情况:有
如果有
类似地,如果刚开始全都是
所以,设
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
main(){
ios::sync_with_stdio(false);
int t; cin>>t;
while(t--){
int n,m,c=2,x=0; cin>>n>>m;
vector<string> a(n+2,string(m+2,'0'));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>a[i][j];
x+=(a[i][j]-=48); // 统计 1 的个数
if(!a[i][j])c=1; // 有 0
}
for(int i=1;i<=m;i++)a[n+1][i]=1;
for(int j=1;j<=n;j++)a[j][m+1]=1;
a[n+1][m+1]=1; // 把边缘全部设为 1,方便处理
for(int i=1;i<=n;i++){
bool f=false;
for(int j=1;j<=m;j++){
if(!a[i][j]){
if(!a[i+1][j]||!a[i][j+1]||!a[i+1][j+1]||(j>1&&!a[i+1][j-1])){
c=0,f=true; break;
} // 判断“空区”
}
}
if(f)break;
}
cout<<x-c<<endl; // 减去 c 后输出
}
return 0;
}