uva 12171 sculpture (超级好题)——yhx

来源:互联网 发布:淘宝代销怎么铺货 编辑:程序博客网 时间:2024/04/30 11:06

  1 #include<cstdio>  2 #include<algorithm>  3 #include<map>  4 #include<cstring>  5 #include<queue>  6 using namespace std;   7 int a[110][110][110],x_map[110],y_map[110],z_map[110],  8 x1_ori[110],y1_ori[60],z1_ori[60],x2_ori[60],y2_ori[60],z2_ori[60],  9 x_move[6]={1,-1,0,0,0,0},y_move[6]={0,0,1,-1,0,0},z_move[6]={0,0,0,0,1,-1}, 10 x_cnt,y_cnt,z_cnt; 11 long long ans_s,ans_v; 12 map<int,int> x_rev,y_rev,z_rev; 13 struct cond 14 { 15     int x,y,z; 16 }c1,c2; 17 queue<cond> q; 18 int main() 19 { 20     int i,j,k,l,m,n,p,x,y,z,t,xx,yy,zz,temp; 21     scanf("%d",&t); 22     while (t--) 23     { 24         memset(a,0,sizeof(a)); 25         memset(x_map,0,sizeof(x_map)); 26         memset(y_map,0,sizeof(y_map)); 27         memset(z_map,0,sizeof(z_map)); 28         memset(x1_ori,0,sizeof(x1_ori)); 29         memset(y1_ori,0,sizeof(y1_ori)); 30         memset(z1_ori,0,sizeof(z1_ori)); 31         memset(x2_ori,0,sizeof(x2_ori)); 32         memset(y2_ori,0,sizeof(y2_ori)); 33         memset(z2_ori,0,sizeof(z2_ori)); 34         x_rev.clear(); 35         y_rev.clear(); 36         z_rev.clear(); 37         scanf("%d",&n); 38         for (i=1;i<=n;i++) 39         { 40             scanf("%d%d%d%d%d%d",&x1_ori[i],&y1_ori[i],&z1_ori[i],&x,&y,&z); 41             x_map[i]=x1_ori[i]; 42             y_map[i]=y1_ori[i]; 43             z_map[i]=z1_ori[i]; 44             x_map[i+n]=x2_ori[i]=x1_ori[i]+x; 45             y_map[i+n]=y2_ori[i]=y1_ori[i]+y; 46             z_map[i+n]=z2_ori[i]=z1_ori[i]+z; 47         } 48         sort(x_map+1,x_map+2*n+1); 49         sort(y_map+1,y_map+2*n+1); 50         sort(z_map+1,z_map+2*n+1); 51         x_cnt=unique(x_map+1,x_map+2*n+1)-(x_map+1); 52         y_cnt=unique(y_map+1,y_map+2*n+1)-(y_map+1); 53         z_cnt=unique(z_map+1,z_map+2*n+1)-(z_map+1); 54         for (i=1;i<=x_cnt;i++) 55           x_rev[x_map[i]]=i; 56         for (i=1;i<=y_cnt;i++) 57           y_rev[y_map[i]]=i; 58         for (i=1;i<=z_cnt;i++) 59           z_rev[z_map[i]]=i;    //以上为离散化 60         x_map[0]=y_map[0]=z_map[0]=0; 61         x_map[x_cnt+1]=y_map[y_cnt+1]=z_map[z_cnt+1]=1005;  //边界,要在外面多围一圈空气。 62         for (i=1;i<=n;i++) 63           for (x=x_rev[x1_ori[i]];x<x_rev[x2_ori[i]];x++) 64             for (y=y_rev[y1_ori[i]];y<y_rev[y2_ori[i]];y++) 65               for (z=z_rev[z1_ori[i]];z<z_rev[z2_ori[i]];z++) 66                 a[x][y][z]=1;   //填充 67         ans_v=1005*1005*1005; 68         ans_s=0; 69         c1.x=c1.y=c1.z=0; 70         q.push(c1); 71         a[0][0][0]=2;  //2表示已经入过队 72         while (!q.empty()) 73         { 74             c1=q.front(); 75             q.pop(); 76             xx=c1.x; 77             yy=c1.y; 78             zz=c1.z; 79             ans_v-=(x_map[xx+1]-x_map[xx])*(y_map[yy+1]-y_map[yy])*(z_map[zz+1]-z_map[zz]); 80              for (i=0;i<=5;i++) 81             { 82                 x=xx+x_move[i]; 83                 y=yy+y_move[i]; 84                 z=zz+z_move[i]; 85                    if (x>=0&&x<=x_cnt&&y>=0&&y<=y_cnt&&z>=0&&z<=z_cnt) 86                 { 87                     if (a[x][y][z]==0)  88                     { 89                         c2.x=x; 90                         c2.y=y; 91                         c2.z=z; 92                         a[x][y][z]=2;   //要在入队时标记,不能在取出时。 93                         q.push(c2); 94                     }  95                     if (a[x][y][z]==1)  96                     { 97                         temp=1; 98                         if (x==xx) temp*=(x_map[xx+1]-x_map[xx]); 99                         if (y==yy) temp*=(y_map[yy+1]-y_map[yy]);100                         if (z==zz) temp*=(z_map[zz+1]-z_map[zz]);101                       ans_s+=temp;   //算面积102                     }103                 }104              }105         }106         printf("%lld %lld\n",ans_s,ans_v);107     }108 }

 

离散化+floodfill。

最开始用的dfs结果RE想到可能是堆栈溢出,改用bfs后AC。

由于体积和面积都是从外面看的,可以从外面一圈“空气”开始floodfill,每次遇到雕塑就加上表面积,因为每一块表面积都会且只会和一块空气接触。体积用总体积减去遇到的空气体积即可。

由于坐标较大,需要离散化。

0 0