汤圆的世界题解
1. 汤圆的世界
题目ID:22963必做题文件操作100分
时间限制: 2000ms
空间限制: 1024000kB
输入文件名: cube.in
输出文件名: cube.out
题目背景
传说很久很久之前,被我们称为汤圆的个体就已经诞生。
汤圆不知道自己从何而来,甚至不知道自己为什么被叫做汤圆。从它拥有意识开始,记忆里就只有自己,和自己所处的这个透明结构,一同被固定在一望无际的蓝天之中。这就是它全部的世界。
题目描述
请大家仔细阅读题面,以免落下任何东西。
汤圆的世界可以被看成一个由 1×1×11×1×1 的小立方体组成的六连通结构。已知这个结构可以被放入一个 n×n×nn×n×n 的大立方体内。
现在,我们会告诉你这个结构的三视图。你需要还原任意一个符合三视图条件,且六连通的结构,或者输出无解。
特别地,我们认为全空不是一种合法的情况。
有关描述结构的具体格式请见下文。
输入格式
从文件 cube.in 中读入数据。
第一行输入一个 tt,表示数据组数。
每一组数据的第一行包含一个正整数 nn,表示结构的大小。
每一组数据接下来的 nn 行,用字符矩阵的形式描述视图 AA。
每一组数据再接下来的 nn 行,用字符矩阵的形式描述视图 BB。
每一组数据再接下来的 nn 行,用字符矩阵的形式描述视图 CC。
不知道是不是为了选手方便,A,B,CA,B,C 按照如下方式定义:

对于矩阵 A,B,CA,B,C 中的每个位置,若该方向上能看到方格,则字符为 #,否则字符为 .。
输出格式
输出到文件 cube.out 中。
对于每组数据,第一行请输出一行字符串 YES 或 NO,表示是否有解。
若输出了 YES,则请继续输出 nn 个 n×nn×n 的字符矩阵。
结构按照如下格式输出:

即从前到后依次输出每一层的方格。若该位置有方格,则输出 #,否则输出 .。
输入输出样例
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
样例
Input 1
6 5 ..#.. ..#.. ..##. ..#.. ##### ###.. #.#.. ..#.# ..#.# ##### ##### #.##. ##### ##### .#### 3 ... .#. ... ... .#. ... ... .#. ... 2 #. .# #. .# .# #. 3 ... ... ... ... ... ... ... ... ... 5 #...# ##### ##### #.#.. ##### ##.## ##### ##### #..## #..## #.### ##### ####. ##... ###.. 5 ##### ##.## ##### ##.## ##### ##### ##### #.#.# ##### ##### ##### ##### #.#.# ##### #####
Output 1
YES ..#.. ..#.. ..... ..... .#### ..#.. ..... ..... ..... ##### ..#.. ..#.. ..##. ..#.. ##### ..... ..... ..... ..... #.##. ..... ..... ..#.. ..#.. ##### YES ... ... ... ... .#. ... ... ... ... NO NO YES #.... #.... ##... #.#.. ###.. #.... ##... ##... ..... ..... ..... ####. ..#.. ..... ..... #.... #.... #.... #.... ##### ....# #...# #.### ..#.. ..#.. YES ##### ##.## ##### ##.## ##### ##### ....# ..... ....# ....# #.#.# ....# ....# ....# ....# ##### ....# ..... ....# ....# ##### ....# ....# ....# ....#
样例解释
对于第一组样例,给出的几何体如下:

对于第二组样例,请注意你构造的结构不需要在地面上、也不需要撑满整个 n×n×nn×n×n 立方体。
对于第三组样例,请注意你构造的结构必须要六连通。
对于第四组样例,请注意你构造的结构不能全空。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
数据范围
对于前 10%10% 的数据,n≤2,∑n≤100n≤2,∑n≤100。
对于前 25%25% 的数据,n≤3,∑n≤100n≤3,∑n≤100。
另有 15%15% 的数据,保证 A,B,CA,B,C 三个视图中分别最多有一个 #。
另有 15%15% 的数据,保证 A,B,CA,B,C 三个视图中分别最多有一个 .。
对于前 70%70% 的数据,n≤50,∑n≤100n≤50,∑n≤100。
对于所有数据,1≤n≤100,∑n≤3001≤n≤100,∑n≤300。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
请注意,样例中的空行仅为方便阅读。实际数据中将不会包含空行,你也不应该输出任何空行。
图片来源于信友队。
附件
思路
直接贪心,能选的都选,然后暴力枚举连通块即可。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long t,n,f[105][105][105],d[105][105][105],cd=0,lk=0,kl=0,asdd=0,qx,qy,qz,lo=0,qf=0;
char a[105][105],b[105][105],c[105][105];
long long at[105][105],bt[105][105],ct[105][105];
long long dx[]={0,1,-1,0,0,0,0};
long long dy[]={0,0,0,1,-1,0,0};
long long dz[]={0,0,0,0,0,1,-1};
struct one{
long long x,y,z;
};
queue<one> q;
int main(){
freopen("cube.in","r",stdin);
freopen("cube.out","w",stdout);
cin>>t;
while(t--){
cin>>n;
asdd=0;
cd=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
f[i][j][k]=1;
d[i][j][k]=0;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
at[i][j]=0;
if(a[i][j]=='.'){
for(int k=1;k<=n;k++){
f[k][i][j]=0;
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>b[i][j];
bt[i][j]=0;
if(b[i][j]=='.'){
for(int k=1;k<=n;k++){
f[j][i][k]=0;
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>c[i][j];
ct[i][j]=0;
if(c[i][j]=='.'){
for(int k=1;k<=n;k++){
f[n-i+1][k][j]=0;
}
}
}
}
lk=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]=='#'){
asdd++;
kl=0;
for(int k=1;k<=n;k++){
if(f[k][i][j]==1){
kl=1;
}
}
if(kl==0){
lk=1;
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(b[i][j]=='#'){
asdd++;
kl=0;
for(int k=1;k<=n;k++){
if(f[j][i][k]==1){
kl=1;
}
}
if(kl==0){
lk=1;
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(c[i][j]=='#'){
asdd++;
kl=0;
for(int k=1;k<=n;k++){
if(f[n-i+1][k][j]==1){
kl=1;
}
}
if(kl==0){
lk=1;
}
}
}
}
if(lk==1||asdd==0){
cout<<"NO"<<endl;
}
else{
lo=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(f[i][j][k]==1&&d[i][j][k]==0){
d[i][j][k]=++cd;
qf=0;
q.push({i,j,k});
while(q.size()!=0){
one a1=q.front();
q.pop();
if(a[a1.y][a1.z]=='#'&&at[a1.y][a1.z]!=cd){
at[a1.y][a1.z]=cd;
qf++;
}
if(b[a1.y][a1.x]=='#'&&bt[a1.y][a1.x]!=cd){
bt[a1.y][a1.x]=cd;
qf++;
}
if(c[n-a1.x+1][a1.z]=='#'&&ct[n-a1.x+1][a1.z]!=cd){
ct[n-a1.x+1][a1.z]=cd;
qf++;
}
for(int o=1;o<=6;o++){
qx=a1.x+dx[o];
qy=a1.y+dy[o];
qz=a1.z+dz[o];
if(qx>=1&&qx<=n&&qy>=1&&qy<=n&&qz>=1&&qz<=n&&f[qx][qy][qz]==1&&d[qx][qy][qz]==0){
d[qx][qy][qz]=cd;
q.push({qx,qy,qz});
}
}
}
if(qf==asdd){
lo=1;
break;
}
}
}
if(lo==1){
break;
}
}
if(lo==1){
break;
}
}
if(lo==1){
cout<<"YES"<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(d[i][j][k]==cd){
cout<<"#";
}
else{
cout<<".";
}
}
cout<<endl;
}
//cout<<endl;
}
}
else{
cout<<"NO"<<endl;
}
}
}
return 0;
}

浙公网安备 33010602011771号