- 题意:果果系统2
- 思路:逆推,用队列存状态,(类似拓扑排序)。每删掉一个块,会影响周围12个网格,8个块(4个涂2下的棱块和4个涂3下的角块)
考试的时候没过因为:
1.两处数组开小(该死的我)
2.check块的时候没有判断比较有色块的个数(思维不够严谨)
- 代码:
#include<bits/stdc++.h>
using namespace std;
const int N=505;
int a[N][N],tot,cnt[N*N],dir[9][2]={{-1,0},{1,0},{0,1},{0,-1},{-1,-1},{1,-1},{1,1},{-1,1}};
struct node {int x,y,val;}ans[N*N];
queue<node> Q;
bool mark[N*N];
int check(int i,int j) {
int k=-1,sz=0;
if(a[i][j]!=-1) k=a[i][j],sz++;
if(a[i+1][j]!=-1) k=a[i+1][j],sz++;
if(a[i+1][j+1]!=-1) k=a[i+1][j+1],sz++;
if(a[i][j+1]!=-1) k=a[i][j+1],sz++;
if(k==-1) return 0;
if(sz==cnt[k]&&(a[i][j]==k||a[i][j]==-1)&&(a[i+1][j]==k||a[i+1][j]==-1)&&(a[i+1][j+1]==k||a[i+1][j+1]==-1)&&(a[i][j+1]==k||a[i][j+1]==-1)) return k;
else return 0;
}
int main() {
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
scanf("%d",&a[i][j]);
cnt[a[i][j]]++;
}
}
while(1) {
for(int i=1;i<n;i++) {
for(int j=1;j<m;j++) {
int t;
if((t=check(i,j))) {
if(!mark[t]) {
Q.push((node){i,j,t});
}
}
}
}
if(Q.empty()) break;
while(!Q.empty()) {
ans[++tot]=Q.front();
int t,x=Q.front().x,y=Q.front().y,w=Q.front().val; Q.pop();
if(mark[w]) {tot--;continue;}
mark[w]=1;
a[x][y]=a[x+1][y]=a[x+1][y+1]=a[x][y+1]=-1;
for(int d=0;d<9;d++) {
int xx=x+dir[d][0],yy=y+dir[d][1];
if(xx<1||yy<1||xx>n||yy>n) continue;
int t=check(xx,yy);
if(t) Q.push((node){xx,yy,t});
}
}
}
for(int i=tot;i>=1;i--) {
int u=ans[i].x,v=ans[i].y;
printf("%d %d %d\n",ans[i].val,u,v);
}
return 0;
}