[arc062E]Building Cubes with AtCoDeer

时间:2021-01-21 13:12:51

Description

传送门

Solution

这道题直接暴力就好。。毕竟只要枚举了前后两个瓷砖的方向和编号,其他瓷砖的颜色就是确定的了。

然而场上我的去重除了问题qaq。

我们钦定在立方体最前面的块编号最小且不可转(这样就可以做到不重不漏),然后枚举最后面的瓷砖编号和方向。

如此,其他四块瓷砖的颜色就已经确定。当我们找了一块瓷砖,就要在map中把该瓷砖的信息删掉以防重复(听大佬说这里的删除也可以用容斥代替)。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
int n;
struct node{int col[];
node nxt(){ return node{col[],col[],col[],col[]};}
friend bool operator <(node a,node b)
{
for (int i=;i<;i++)
if (a.col[i]!=b.col[i]) return a.col[i]<b.col[i];
return ;
}
}a[],a1,a2,a3,a4;
map<node,int>mp;
void insert(node x,int v)
{for (int i=;i<;i++,x=x.nxt()) mp[x]+=v;} node xx,yy;
int id1;
ll ans,re;
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d%d%d%d",&a[i].col[],&a[i].col[],&a[i].col[],&a[i].col[]);
insert(a[i],);
}
for (int i=;i<=n;i++)
{
insert(a[i],-);
for (int j=i+;j<=n;j++)
{
insert(a[j],-);
for (int t=;t<;t++)
{
a1=node{a[j].col[],a[i].col[],a[i].col[],a[j].col[]};
a2=node{a[i].col[],a[j].col[],a[j].col[],a[i].col[]};
a3=node{a[j].col[],a[j].col[],a[i].col[],a[i].col[]};
a4=node{a[i].col[],a[i].col[],a[j].col[],a[j].col[]};
a[j]=a[j].nxt();
if (mp[a1]==||mp[a2]==||mp[a3]==||mp[a4]==) continue;
re=;
re*=mp[a1];insert(a1,-);
re*=mp[a2];insert(a2,-);
re*=mp[a3];insert(a3,-);
re*=mp[a4];
insert(a1,);insert(a2,);insert(a3,);
ans+=re; }
insert(a[j],);
}
}
cout<<ans;
}