【arc062e】Building Cubes with AtCoDeer

Description

STL有n块瓷砖,编号从1到n,并且将这个编号写在瓷砖的正中央;

瓷砖的四个角上分别有四种颜色(可能相等可能不相等),并且用Ci,0,Ci,1,Ci,2,Ci,3分别表示左上、右上、右下、左下的颜色。颜色有1000种,编号从0到999。

现在STL想知道,从这n块瓷砖中选出不同的6块,能围成多少本质不同的合法的立方体。

一个立方体被称为合法的,当且仅当瓷砖有编号的一侧在外面,并且立方体的每个顶点处的三个颜色相同。

注意,由于瓷砖的中间是写着编号的,因此将一个瓷砖旋转90度之后,这个瓷砖会发生变化,也就是说一块瓷砖可以被用作四个方向(哪怕旋转后四个角的颜色对应相等)。

两个立方体被称作是本质相同的,当且仅当存在在空间中旋转一个立方体的方式,使其和第二个立方体一模一样(包括每面瓷砖上编号的方向)。


Solution

n最大为400,显然可以暴力解决。

我们可以发现,当一个立方体中,只要确定了任意两个相对的面,就可唯一确定整个立方体。

因此我们枚举相对两面编号及编号方向,用map储存瓷砖,计算方案即可。

ps:由于正方形可旋转,因此存入map时,要将旋转4次的结果都存入map中。

Code

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<map>
 5 using namespace std;
 6 #define hash func
 7 typedef long long ll;
 8 int n,c[410][4];
 9 ll ans=0,h[410];
10 map<ll,int>mp;
11 ll hash(ll a,ll b,ll c,ll d){
12     return a<<30|b<<20|c<<10|d;
13 }
14 void add(ll x,int k){
15     for(int i=4;i;x=x>>10|(x&1023)<<30,i--)
16         mp[x]+=k;
17     return;
18 }
19 int main(){
20     mp.clear();
21     scanf("%d",&n);
22     for(int i=1;i<=n;i++){
23         scanf("%d%d%d%d",c[i]+0,c[i]+1,c[i]+2,c[i]+3);
24         h[i]=hash(c[i][0],c[i][1],c[i][2],c[i][3]);
25         add(h[i],1);
26     }
27     for(int i=1;i<n-4;i++){
28         add(h[i],-1);
29         for(int j=i+1;j<=n;j++){
30             add(h[j],-1);
31             for(int k=0;k<4;k++){
32                 ll a[4];
33                 a[0]=hash(c[i][3],c[i][2],c[j][(k+1)%4],c[j][k]);
34                 a[1]=hash(c[i][2],c[i][1],c[j][(k+2)%4],c[j][(k+1)%4]);
35                 a[2]=hash(c[i][1],c[i][0],c[j][(k+3)%4],c[j][(k+2)%4]);
36                 a[3]=hash(c[i][0],c[i][3],c[j][k],c[j][(k+3)%4]);
37                 if(mp[a[0]]==0||mp[a[1]]==0||mp[a[2]]==0||mp[a[3]]==0)
38                     continue;
39                 ll res=1;
40                 for(int l=0;l<4;l++){
41                     res*=mp[a[l]];
42                     add(a[l],-1);
43                 }
44                 ans+=res;
45                 for(int l=0;l<4;l++)
46                     add(a[l],1);
47             }
48             add(h[j],1);
49         }
50     }
51     printf("%lld\n",ans);
52     return 0;
53 }

转载于:https://www.cnblogs.com/gzez181027/p/arc062e.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
Marching Cubes算法是一种常用的三维体数据表面重建算法。它可以将一个体数据集转化为连续的多边形网格模型。 在三维体数据中,每个体素的值表示其在某一属性上的特征,如密度、压力等。Marching Cubes算法首先将整个体数据集划分为无数个小立方体,每个小立方体包含8个顶点。然后根据每个小立方体顶点所代表的属性值与事先设定的阈值进行比较,确定该顶点是否在表面上。若在表面上,就将相应顶点连接起来组成一个面,并将该面连接到整个网格模型上。 得到的多边形网格模型可以用于可视化、仿真和分析等应用。Marching Cubes算法具有简单、高效的特点,适用于各种不规则的三维体数据集。它广泛应用于医学图像处理、地质勘探、计算机动画等领域。 然而,Marching Cubes算法也存在一些限制。首先,它在重建过程中产生的多边形可能存在不连续性和拓扑错误。为了解决这个问题,后续研究提出了一些改进算法,如Dual Marching Cubes和Extended Marching Cubes。其次,Marching Cubes算法对数据集的分辨率要求较高,对于过于细致的结构可能无法很好地重建。 总的来说,Marching Cubes算法在三维体数据表面重建领域具有重要的应用价值,其简单、高效的特点使其成为一种常用的算法。随着相关技术的不断发展,对Marching Cubes算法的改进和优化将进一步推动其在各个领域的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值