• 题意:果果系统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;
    }