2018.09.20 atcoder Building Cubes with AtCoDeer(枚举)

版权声明:随意转载哦......但还是请注明出处吧: https://blog.csdn.net/dreaming__ldx/article/details/82780312

传送门
有个十分显然的结论,只用枚举前后两个面就可以知道所有的面的颜色。
于是可以 O ( n 2 ) O(n^2) 枚举前后两个面然后用map乱搞求贡献。
发现这样算出来会多算两倍(打表证明)于是答案除以3。
代码:

#include<bits/stdc++.h>
#define ll long long
#define N 405
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int n,col[N][4];
ll ans=0,mp[N][4];
map<ll,int>cnt;
inline ll idx(int a,int b,int c,int d){return 1ll*a+1ll*b*1000+1ll*c*1000000+1ll*d*1000000000;}
int main(){
	n=read();
	for(int i=1;i<=n;++i)for(int j=0;j<=3;++j)col[i][j]=read();
	for(int i=1;i<=n;++i){
		mp[i][0]=idx(col[i][0],col[i][1],col[i][2],col[i][3]);
		mp[i][1]=idx(col[i][1],col[i][2],col[i][3],col[i][0]);
		mp[i][2]=idx(col[i][2],col[i][3],col[i][0],col[i][1]);
		mp[i][3]=idx(col[i][3],col[i][0],col[i][1],col[i][2]);
		for(int j=0;j<4;++j)++cnt[mp[i][j]];
	}
	for(int i=1;i<=n;++i){
		for(int j=0;j<4;++j)--cnt[mp[i][j]];
		for(int j=i+1;j<=n;++j){
			if(i==j)continue;
			for(int k=0;k<4;++k)--cnt[mp[j][k]];
			for(int k=0;k<4;++k){
				ll tmp[16],ttmp=1;
				tmp[0]=idx(col[i][0],col[i][3],col[j][k],col[j][(k+3)%4]);
				tmp[4]=idx(col[j][(k+3)%4],col[i][0],col[i][3],col[j][k]);
				tmp[8]=idx(col[j][k],col[j][(k+3)%4],col[i][0],col[i][3]);
				tmp[12]=idx(col[i][3],col[j][k],col[j][(k+3)%4],col[i][0]);
				tmp[1]=idx(col[i][1],col[i][0],col[j][(k+3)%4],col[j][(k+2)%4]);
				tmp[5]=idx(col[j][(k+2)%4],col[i][1],col[i][0],col[j][(k+3)%4]);
				tmp[9]=idx(col[j][(k+3)%4],col[j][(k+2)%4],col[i][1],col[i][0]);
				tmp[13]=idx(col[i][0],col[j][(k+3)%4],col[j][(k+2)%4],col[i][1]);
				tmp[2]=idx(col[i][2],col[i][1],col[j][(k+2)%4],col[j][(k+1)%4]);
				tmp[6]=idx(col[j][(k+1)%4],col[i][2],col[i][1],col[j][(k+2)%4]);
				tmp[10]=idx(col[j][(k+2)%4],col[j][(k+1)%4],col[i][2],col[i][1]);
				tmp[14]=idx(col[i][1],col[j][(k+2)%4],col[j][(k+1)%4],col[i][2]);
				tmp[3]=idx(col[i][3],col[i][2],col[j][(k+1)%4],col[j][k]);
				tmp[7]=idx(col[j][k],col[i][3],col[i][2],col[j][(k+1)%4]);
				tmp[11]=idx(col[j][(k+1)%4],col[j][k],col[i][3],col[i][2]);
				tmp[15]=idx(col[i][2],col[j][(k+1)%4],col[j][k],col[i][3]);
				if(cnt[tmp[0]]==0||cnt[tmp[1]]==0||cnt[tmp[2]]==0||cnt[tmp[3]]==0)continue;
				for(int l=0;l<4;++l){
					ttmp*=cnt[tmp[l]];
					for(int m=l;m<16;m+=4)--cnt[tmp[m]];
				}
				for(int l=0;l<16;++l)++cnt[tmp[l]];
				ans+=ttmp;
			}
			for(int k=0;k<4;++k)++cnt[mp[j][k]];
		}
		for(int j=0;j<4;++j)++cnt[mp[i][j]];
	}
	cout<<ans/3;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/dreaming__ldx/article/details/82780312