​http://codeforces.com/contest/1638/problem/D​

按题意着色则需要考虑先后次序问题,次序问题一般用拓扑解决。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;

struct node
{
int x,y,c;
};

queue <node> que;
node ans[maxn*maxn];
int ary[maxn][maxn],book[maxn][maxn],col[maxn*maxn];
int n,m,len;

int judge(int x,int y)
{
int i,j,tx,ty,cnt,zero,syt;
cnt=0,zero=0,syt=1;
for(i=0;i<=1;i++){
for(j=0;j<=1;j++){
if(!col[ary[x+i][y+j]]){
col[ary[x+i][y+j]]=1;
cnt++;
if(ary[x+i][y+j]==0){
zero=1;
}
else{
syt=ary[x+i][y+j];
}
}
}
}
for(i=0;i<=1;i++){
for(j=0;j<=1;j++){
col[ary[x+i][y+j]]=0;
}
}
if(cnt==1||cnt==2&&zero){
return syt;
}
else{
return -1;
}
}

bool toposort()
{
node cur,tmp;
int i,j,k,cnt,res;
len=0;
for(i=1;i<=n-1;i++){
for(j=1;j<=m-1;j++){
if(ary[i][j]==ary[i+1][j]&&ary[i][j]==ary[i][j+1]&&ary[i][j]==ary[i+1][j+1]){
tmp.x=i,tmp.y=j,tmp.c=ary[i][j];
que.push(tmp);
book[tmp.x][tmp.y]=1;
len++;
ans[len]=tmp;
}
}
}
while(!que.empty()){
cur=que.front();
que.pop();
ary[cur.x][cur.y]=0,ary[cur.x+1][cur.y]=0,ary[cur.x][cur.y+1]=0,ary[cur.x+1][cur.y+1]=0;
//printf("%d %d %d\n",cur.x,cur.y,cur.c);
for(i=-1;i<=1;i++){
for(j=-1;j<=1;j++){
tmp.x=cur.x+i,tmp.y=cur.y+j;
if(tmp.x<1||tmp.x+1>n||tmp.y<1||tmp.y+1>m){
continue;
}
res=judge(tmp.x,tmp.y);
if(!book[tmp.x][tmp.y]&&res!=-1){
tmp.c=res;
que.push(tmp);
book[tmp.x][tmp.y]=1;
len++;
ans[len]=tmp;
}
}
}
}
memset(book,0,sizeof(book));
cnt=0;
for(k=1;k<=len;k++){
for(i=0;i<=1;i++){
for(j=0;j<=1;j++){
if(!book[ans[k].x+i][ans[k].y+j]){
book[ans[k].x+i][ans[k].y+j]=1;
cnt++;
}
}
}
}
return cnt==n*m;
}

int main()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&ary[i][j]);
}
}
if(toposort()){
printf("%d\n",len);
for(i=len;i>=1;i--){
printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].c);
}
}
else{
printf("-1\n");
}


return 0;
}