刘汝佳大神书上的原题,思路是寻找六个视图中颜色的冲突,只要发现方块的颜色在六个视图中产生了冲突,就把这个方块删掉,直到没有冲突发生时,整个大方阵的方块个数就是可以达到的最多的了。
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
map<int, char> predict_arr;
char arr[15][15][15]; //记录当前方阵哪些方块是存在的
//各个面的视图
char arr_front[15][15];
char arr_left[15][15];
char arr_back[15][15];
char arr_right[15][15];
char arr_top[15][15];
char arr_bottom[15][15];
int _hash(int x, int y, int z){
return x + y * 15 + z*15*15;
}
void func(int n){
int x, y, z, i, j;
int hash_v;
predict_arr.clear();
bool conflict; //是否有冲突
for(x=1; x<=n; x++)
for(y=1; y<=n; y++)
for(z=1; z<=n; z++)
arr[x][y][z] = 1;
//先把能看穿的部分的方块全部删掉
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_front[i][j] == '.'){
for(z = 1; z<=n; z++)
arr[j][i][z] = 0;
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_left[i][j] == '.'){
for(x=1; x<=n; x++)
arr[x][i][n+1-j] = 0;
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_back[i][j] == '.'){
for(z=1; z<=n; z++)
arr[n+1-j][i][z] = 0;
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_right[i][j] == '.'){
for(x=1; x<=n; x++)
arr[x][i][j] = 0;
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_top[i][j] == '.'){
for(y=1; y<=n; y++)
arr[j][y][n+1-i] = 0;
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_bottom[i][j] == '.'){
for(y=1; y<=n; y++)
arr[j][y][i] = 0;
}
}
}
conflict = true;
while(conflict){
conflict = false;
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_front[i][j] != '.'){
z = 1;
while(arr[j][i][z] != 1) z++;
hash_v = _hash(j, i, z);
if(predict_arr.find(hash_v) == predict_arr.end())
predict_arr[hash_v] = arr_front[i][j];
else if(predict_arr[hash_v] != arr_front[i][j]){
arr[j][i][z] = 0;
conflict = true;
}
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_left[i][j] != '.'){
x = 1;
while(arr[x][i][n+1-j] != 1) x++;
hash_v = _hash(x, i, n+1-j);
if(predict_arr.find(hash_v) == predict_arr.end())
predict_arr[hash_v] = arr_left[i][j];
else if(predict_arr[hash_v] != arr_left[i][j]){
arr[x][i][n+1-j] = 0;
conflict = true;
}
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_back[i][j] != '.'){
z = n;
while(arr[n+1-j][i][z] != 1) z--;
hash_v = _hash(n+1-j, i, z);
if(predict_arr.find(hash_v) == predict_arr.end())
predict_arr[hash_v] = arr_back[i][j];
else if(predict_arr[hash_v] != arr_back[i][j]){
arr[n+1-j][i][z] = 0;
conflict = true;
}
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_right[i][j] != '.'){
x = n;
while(arr[x][i][j] != 1) x--;
hash_v = _hash(x, i, j);
if(predict_arr.find(hash_v) == predict_arr.end())
predict_arr[hash_v] = arr_right[i][j];
else if(predict_arr[hash_v] != arr_right[i][j]){
arr[x][i][j] = 0;
conflict = true;
}
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_top[i][j] != '.'){
y = 1;
while(arr[j][y][n+1-i] != 1) y++;
hash_v = _hash(j, y, n+1-i);
if(predict_arr.find(hash_v) == predict_arr.end())
predict_arr[hash_v] = arr_top[i][j];
else if(predict_arr[hash_v] != arr_top[i][j]){
arr[j][y][n+1-i] = 0;
conflict = true;
}
}
}
}
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(arr_bottom[i][j] != '.'){
y = n;
while(arr[j][y][i] != 1) y--;
hash_v = _hash(j, y, i);
if(predict_arr.find(hash_v) == predict_arr.end())
predict_arr[hash_v] = arr_bottom[i][j];
else if(predict_arr[hash_v] != arr_bottom[i][j]){
arr[j][y][i] = 0;
conflict = true;
}
}
}
}
}
int sum;
sum = 0;
for(x=1; x<=n; x++)
for(y=1; y<=n; y++)
for(z=1; z<=n; z++)
if(arr[x][y][z])
sum++;
printf("Maximum weight: %d gram(s)\n", sum);
}
int main(void){
int n, i, j;
char buf[20];
//freopen("input.dat", "r", stdin);
while(scanf("%d", &n), n){
for(i=1; i<=n; i++){
for(j=1; j<=6; j++){
scanf("%s", buf);
switch(j){
case 1:
strcpy(arr_front[i]+1, buf);
break;
case 2:
strcpy(arr_left[i]+1, buf);
break;
case 3:
strcpy(arr_back[i]+1, buf);
break;
case 4:
strcpy(arr_right[i]+1, buf);
break;
case 5:
strcpy(arr_top[i]+1, buf);
break;
case 6:
strcpy(arr_bottom[i]+1, buf);
break;
}
}
}
func(n);
}
return 0;
}