我的代码已经写到不能再暴力了
显示第四个点有可行解但输出 -1。
#include<bits/stdc++.h>
using namespace std;
#define N 1003
#define LL long long
#define INF 0x3f3f3f3f
int n,m,h[N][N],tp,tot;
struct node{
int x,y,k;
}stk[8000003],ans[8000003];
int dxb[4]={-1,0,1,0}; //检查边的方向数组(使用见下面的函数)
int dxbfz[8]={0,0,0,1,1,1,0,1}; //检查边的方向辅助数组(使用见下面的函数)
int dyb[4]={0,1,0,-1};
int dybfz[8]={0,1,1,1,0,1,0,0};
int dxj[4]={-1,-1,1,1}; //检查角的方向数组(使用见下面的函数)
int dxjfz[12]={1,0,0,0,0,1,0,1,1,1,1,0}; //检查角的方向辅助数组(使用见下面的函数)
int dyj[4]={-1,1,1,-1};
int dyjfz[12]={0,0,1,0,1,1,1,1,0,1,0,0};
void chkb(int x,int y){ //检查被删除大方格的上下左右四条边(即上下左右是否有一半的大方格)
for(int d=0;d<4;d++){
int xx=x+dxb[d],yy=y+dyb[d];
//被操作的点,即需要在答案中输出的点
if(xx<1||xx>=n||yy<1||yy>=m) continue;
int xa=xx+dxbfz[d*2],ya=yy+dybfz[d*2];
int xb=xx+dxbfz[d*2+1],yb=yy+dybfz[d*2+1];
//上面两个是需要检查的点,即上述“一半的大方格”中的两个点
int num=0;
if(h[xa][ya]) num=h[xa][ya];
if(h[xb][yb]) num=h[xb][yb];
if(!h[xa][ya]) h[xa][ya]=num;
if(!h[xb][yb]) h[xb][yb]=num;
//这五行意为检查点是否都为零,若有点不为零则把为零的点全改为那个点的值(方便检查)
if(num&&h[xa][ya]==num&&h[xb][yb]==num){ //如果两个点值相等则可能为上述“一半的大方格”,加入答案
stk[++tp]={xx,yy,num},ans[++tot]={xx,yy,num};
h[xa][ya]=h[xb][yb]=0;
}
}
}
void chkj(int x,int y){ //检查被删除大方格的四个角(即四个角是否有缺一角的大方格)
for(int d=0;d<4;d++){
int xx=x+dxj[d],yy=y+dyj[d]; //被操作的点
if(xx<1||xx>=n||yy<1||yy>=m) continue;
int xa=xx+dxjfz[d*3],ya=yy+dyjfz[d*3];
int xb=xx+dxjfz[d*3+1],yb=yy+dyjfz[d*3+1];
int xc=xx+dxjfz[d*3+2],yc=yy+dyjfz[d*3+2]; //需检查的点
int num=0;
if(h[xa][ya]) num=h[xa][ya];
if(h[xb][yb]) num=h[xb][yb];
if(h[xc][yc]) num=h[xc][yc];
if(!h[xa][ya]) h[xa][ya]=num;
if(!h[xb][yb]) h[xb][yb]=num;
if(!h[xc][yc]) h[xc][yc]=num; //同上个函数
if(num&&h[xa][ya]==num&&h[xb][yb]==num&&h[xc][yc]==num){
stk[++tp]={xx,yy,num},ans[++tot]={xx,yy,num};
h[xa][ya]=h[xb][yb]=h[xc][yc]=0;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&h[i][j]);
for(int i=1;i<n;++i)
for(int j=1;j<m;++j)
if(h[i+1][j]==h[i][j]&&h[i][j+1]==h[i][j]&&h[i+1][j+1]==h[i][j]){ //如果初始有完整的大方格则直接清空加入答案
stk[++tp]={i,j,h[i][j]},ans[++tot]={i,j,h[i][j]};
h[i][j]=h[i+1][j]=h[i][j+1]=h[i+1][j+1]=0;
}
while(tp){ //每次取栈顶检查四周是否有可能完整的大方格
int x=stk[tp].x,y=stk[tp].y;
tp--,chkb(x,y),chkj(x,y);
}
bool fl=false;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(h[i][j]) fl=true; //如果仍有点未被染色则无解
if(fl) puts("-1");
else{
printf("%d\n",tot);
for(int i=tot;i;--i) //输出答案
printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].k);
}
return 0;
}