题目链接
题目大意
就是给你一个\(n*m\)的矩阵,你每次可以对一个\(2*2\)的方格染色变成\(k\),要求你最多染\(n*m\)次后,变成矩阵的样
子,每个点可以重复染色
题目思路
这个题目就是会覆盖导致问题不好解决
那么就考虑逆向染色那么就不会覆盖+bfs就可以解决此问题,具体看代码
代码
#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pii pair<int,int>
using namespace std;
const int maxn=1e3+5,mod=998244353;
int n,m;
int a[maxn][maxn];
int check(int x,int y){
if(x<1||y<1||x>=n||y>=m) return 0;
set<int> st;
for(int i=0;i<=1;i++){
for(int j=0;j<=1;j++){
if(a[x+i][y+j]==-1) continue;
st.insert(a[x+i][y+j]);
}
}
if((int)st.size()!=1){
return 0;
}else{
return *st.begin();
}
}
struct node{
int x,y,c;
};
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
queue<node> que;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(check(i,j)){
que.push({i,j,check(i,j)});
}
}
}
vector<node> ans;
while(!que.empty()){
node now=que.front();
que.pop();
if(check(now.x,now.y)!=now.c) continue;
// 加这句话
ans.push_back(now);
for(int i=0;i<=1;i++){
for(int j=0;j<=1;j++){
a[now.x+i][now.y+j]=-1;
}
}
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
if(check(now.x+i,now.y+j)){
que.push({now.x+i,now.y+j,check(now.x+i,now.y+j)});
}
}
}
}
bool flag=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]!=-1){
flag=0;
}
}
}
if(flag){
printf("%d\n",ans.size());
reverse(ans.begin(),ans.end());
for(auto x:ans){
printf("%d %d %d\n",x.x,x.y,x.c);
}
}else{
printf("-1\n");
}
return 0;
}