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

  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,每次遇到雕塑就加上表面积,因为每一块表面积都会且只会和一块空气接触。体积用总体积减去遇到的空气体积即可。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值