UVA 1030 Image Is Everything

https://vjudge.net/problem/UVA-1030

题目

有个机器人会对一个由相同大小的正方体组成的物品拍照(这个物品不一定是一块),每个侧面都会拍一张,并且计算最大重量(一个小正方体重1g,六个面颜色相同),你需要编写确定重量的程序。如果颜色为“.”表示这个位置直接可以看穿这个物品。

Sample Input

3
.R. YYR .Y. RYY .Y. .R.
GRB YGR BYG RBY GYB GRB
.R. YRR .Y. RRY .R. .Y.
2
ZZ ZZ ZZ ZZ ZZ ZZ
ZZ ZZ ZZ ZZ ZZ ZZ
0

Sample Output

Maximum weight: 11 gram(s)
Maximum weight: 8 gram(s)

题解

首先看作整体,然后运用归纳法,删除存在矛盾的方块,同时标记受到影响的方块,在下一次检测它们。

矛盾只能靠删除解决,而且对于一个有矛盾的方块来说,删除其他方块不能消除颜色的矛盾。

AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#include<unordered_map>
#define REP(i,a,b) for(register int i=(a); i<(b); i++)
#define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
#define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
int n;
char sfs[6][10][10];
struct node {
	char m[6];
	bool no, vis;
};
node fks[10][10][10];
inline void paint() {
	REP(i,0,n) REP(j,0,n) REP(k,0,n) memset(&fks[i][j][k],0,sizeof(fks[i][j][k]));
	PERE(y,n-1,0) REP(x,0,n) fks[x][y][0].m[0]=sfs[0][n-1-y][x]; //0
	PERE(y,n-1,0) PERE(z,n-1,0) fks[0][y][z].m[1]=sfs[1][n-1-y][n-1-z]; //1
	PERE(y,n-1,0) PERE(x,n-1,0) fks[x][y][n-1].m[2]=sfs[2][n-1-y][n-1-x]; //2
	PERE(y,n-1,0) REP(z,0,n) fks[n-1][y][z].m[3]=sfs[3][n-1-y][z]; //3
	PERE(z,n-1,0) REP(x,0,n) fks[x][n-1][z].m[4]=sfs[4][n-1-z][x]; //4
	REP(z,0,n) REP(x,0,n) fks[x][0][z].m[5]=sfs[5][z][x]; //5
}
struct id {
	char x,y,z;
};
queue<id> q;
int ans;
inline void del(int x, int y, int z) {
#define A(a,b,c) if(!fks[a][b][c].vis) {fks[a][b][c].vis=1; q.push((id){(char)(a),(char)(b),(char)(c)});}
	fks[x][y][z].no=true;
	if(fks[x][y][z].m[0]) REP(i,z+1,n) if(!fks[x][y][i].no) {fks[x][y][i].m[0]=fks[x][y][z].m[0]; A(x,y,i); break;}
	if(fks[x][y][z].m[1]) REP(i,x+1,n) if(!fks[i][y][z].no) {fks[i][y][z].m[1]=fks[x][y][z].m[1]; A(i,y,z); break;}
	if(fks[x][y][z].m[2]) PERE(i,z-1,0) if(!fks[x][y][i].no) {fks[x][y][i].m[2]=fks[x][y][z].m[2]; A(x,y,i); break;}
	if(fks[x][y][z].m[3]) PERE(i,x-1,0) if(!fks[i][y][z].no) {fks[i][y][z].m[3]=fks[x][y][z].m[3]; A(i,y,z); break;}
	if(fks[x][y][z].m[4]) PERE(i,y-1,0) if(!fks[x][i][z].no) {fks[x][i][z].m[4]=fks[x][y][z].m[4]; A(x,i,z); break;}
	if(fks[x][y][z].m[5]) REP(i,y+1,n) if(!fks[x][i][z].no) {fks[x][i][z].m[5]=fks[x][y][z].m[5]; A(x,i,z); break;}
	ans++;
}
bool isok(int x, int y, int z) {
	char col=0;
	REP(i,0,6) if(fks[x][y][z].m[i]!=0) {col=fks[x][y][z].m[i]; break;}
	if(col=='.') return false;
	if(col==0) return true;
	REP(i,0,6) if(fks[x][y][z].m[i]!=0 && fks[x][y][z].m[i]!=col) return false;
	return true;
}

int main() {
	while(~scanf("%d", &n) && n) {
		ans=0;
		REP(i,0,n) REP(k,0,6) REP(j,0,n) {
			sfs[k][i][j]=getchar();
			if(sfs[k][i][j]<=' ') sfs[k][i][j]=getchar();
		}
		paint();
		REP(i,0,n) REP(j,0,n) {
			if(!isok(i,j,0)) A(i,j,0);
			if(!isok(i,j,n-1)) A(i,j,n-1);
		}
		REP(i,0,n) REP(k,0,n) {
			if(!isok(i,0,k)) A(i,0,k);
			if(!isok(i,n-1,k)) A(i,n-1,k);
		}
		REP(j,0,n) REP(k,0,n) {
			if(!isok(0,j,k)) A(0,j,k);
			if(!isok(n-1,j,k)) A(n-1,j,k);
		}
		while(!q.empty()) {
			id now = q.front(); q.pop();
			fks[now.x][now.y][now.z].vis=0;
			if(!isok(now.x, now.y, now.z)) del(now.x, now.y, now.z);
		}
		printf("Maximum weight: %d gram(s)
", n*n*n-ans);
	}
}
原文地址:https://www.cnblogs.com/sahdsg/p/12337646.html