AtCoder Regular Contest 062 E - AtCoDeerくんと立方体づくり / Building Cubes with AtCoDeer

题目传送门:https://arc062.contest.atcoder.jp/tasks/arc062_c

题目大意:

给你\(N\)块正方形木板,每块木板四角有四种颜色(可以相同),木板中央有编号,求选出6块不同的板子,围成的本质不同的合法立方体的个数。一个合法立方体,当且仅当木板有编号的一面在外面,且立方体顶点处的三个颜色相同。由于编号的存在,木板可以有4种形态。两个立方体本质相同,当且仅当存在一种空间旋转方式,使得两个立方体一模一样(包括编号方向)

没想到这题巨暴力……当我们确定对面的两块木板后,整个立方体就确定了……暴力枚举,然后去重一下就做完了……

/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Fi first
#define Se second
#define inf 0x7f7f7f7f
#define min(x,y) (x<y?x:y)
#define max(x,y) (x>y?x:y)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
    static char buf[1000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
    int x=0,f=1; char ch=gc();
    for (;ch<'0'||ch>'9';ch=gc())   if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0';
    return x*f;
}
inline int read(){
    int x=0,f=1; char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar())  if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=getchar())    x=(x<<3)+(x<<1)+ch-'0';
    return x*f;
}
inline void print(int x){
    if (x<0)    putchar('-'),x=-x;
    if (x>9)    print(x/10);
    putchar(x%10+'0');
}
const int N=4e2;
int C[N+10][4];
ll v[N+10];
map<ll,int>Mp;
ll Hash(int a,int b,int c,int d){return ((ll)a<<30)|((ll)b<<20)|((ll)c<<10)|(ll)d;}
void Add(ll x,int v){//一种Hash方法
    for (int i=0;i<4;i++,x=(x>>10)|((x&1023)<<30)){
        if (Mp.find(x)==Mp.end())   Mp.insert(map<ll,int>::value_type(x,0));
        Mp.find(x)->Se+=v;
    }
}
int main(){
    int n=read(); ll Ans=0;
    for (int i=1;i<=n;i++){
        for (int j=0;j<4;j++)
            C[i][j]=read();
        v[i]=Hash(C[i][0],C[i][1],C[i][2],C[i][3]);
        Add(v[i],1);
    }
    for (int i=1;i<n-4;i++){
        Add(v[i],-1);
        for (int j=i+1;j<=n;j++){
            Add(v[j],-1);
            for (int k=0;k<4;k++){
                static ll A[4];
                A[0]=Hash(C[i][1],C[i][0],C[j][(k+1)%4],C[j][k    %4]);
                A[1]=Hash(C[i][2],C[i][1],C[j][k    %4],C[j][(k+3)%4]);
                A[2]=Hash(C[i][3],C[i][2],C[j][(k+3)%4],C[j][(k+2)%4]);
                A[3]=Hash(C[i][0],C[i][3],C[j][(k+2)%4],C[j][(k+1)%4]);
                //自己画图带入一下即可
                int a=0,b=0,c=0,d=0;
                map<ll,int>::iterator it;
                if ((it=Mp.find(A[0]))==Mp.end())   continue;
                else    a=it->Se;
                if ((it=Mp.find(A[1]))==Mp.end())   continue;
                else    b=it->Se;
                if ((it=Mp.find(A[2]))==Mp.end())   continue;
                else    c=it->Se;
                if ((it=Mp.find(A[3]))==Mp.end())   continue;
                else    d=it->Se;
                if (!a||!b||!c||!d) continue;
                ll res=1;
                for (int l=0;l<4;l++){
                    res*=Mp.find(A[l])->Se;
                    Add(A[l],-1);
                }
                Ans+=res;
                for (int l=0;l<4;l++)   Add(A[l],1);
            }
            Add(v[j],1);
        }
    }
    printf("%lld\n",Ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Wolfycz/p/10072714.html

时间: 2024-08-29 13:30:43

AtCoder Regular Contest 062 E - AtCoDeerくんと立方体づくり / Building Cubes with AtCoDeer的相关文章

AtCoder Regular Contest 098

AtCoder Regular Contest 098 C - Attention 题意 给定一个只包含"E","W"字符串,可以花一的花费使他们互相转换.选定一个位置,使位置左边的字符都变成E,右边都变成W所需要的最小花费. 分析 这题纯粹是签到题,做两个前缀和然后直接加就可以了. #include <iostream> #include <cmath> #include <cstring> #include <cstdi

AtCoder Regular Contest 095

AtCoder Regular Contest 095 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个A和Y个B最小花费使多少. 分析: 明显的发现肯定买性价比更高的方案,分情况讨论一下,如果\(a+b<=2*c\),那么明显的先买足c到A,B中较小的一个,然后再比较一下剩下的那个的单价和\(2*c\)的大小. A[ans=] -->|a+b<=2*c| B(A*a+B*b) A -->

AtCoder Regular Contest 094

AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几次操作将三个数变为相同的数. 分析: 可以发现如果三个数的奇偶性相同直接加就可以了,对于奇偶性不同的,先把奇偶性相同的两个数都+1,然后按照相同的处理就可以了.可以证明没有更好的方案. #include <bits/stdc++.h> using namespace std; int a,b,c,

AtCoder Regular Contest 103

AtCoder Regular Contest 103 一些吐槽 参加的第一场\(ARC\):一个模拟 + 三个构造 没见过比这更令人感动的题型设置了(简直就是针对我(TAT)) . 感觉全场就我一个人\(E\)题WA了四遍才过....... C-//// 题目大意: 网址 给定一个串\(S\),要求修改一些字符,使得串满足以下条件: \(S_i = S_{i+2}\) \(S_1 \neq S_2\) . 问最少需要修改多少个字符. 题解: 无脑统计一下奇数和偶数格的每种种类. 然后在最大值和

AtCoder Regular Contest 075 E - Meaningful Mean 树状数组求顺序对, 前缀和

题目链接: http://arc075.contest.atcoder.jp/tasks/arc075_c 题意: 给你一个序列和一个数k,求有多少对l,r,使得a[l]+a[l+1]+...+a[r]的算术平均数大于等于k 1≤N≤2×10^5 1≤K≤10^9 1≤ai≤10^9 思路: 首先对于所有数减去k,这样就不用除(r-l+1), 然后我们发现所求的就是有多少对l,r,使得sum[r]-sum[l-1] >= 0, sum是减去k之后的序列的前缀和 用树状数组对sum求有多少个顺序对

AtCoder Regular Contest 063 E:Integers on a Tree

题目传送门:https://arc063.contest.atcoder.jp/tasks/arc063_c 题目翻译 给你一个树,上面有\(k\)个点有权值,问你是否能把剩下的\(n-k\)个点全部填上权值,使得每条边链接的两个点权值相差\(1\),如果可以做到需要输出任意一组方案. 题解 我们考虑每条边权值为\(1\)或\(-1\),那么相当于黑白染色一样,所有点权值的奇偶性也都是确定的.如果与读入的\(k\)个点中某个点相冲突了就\(GG\).另外每个点的取值范围都可以转化成一段区间\([

AtCoder Regular Contest 072 E:Alice in linear land

题目传送门:https://arc072.contest.atcoder.jp/tasks/arc072_c 题目翻译 给你一个数组\(D\),然后给你一个操作序列\(d\),每次操作可以将\(D\)变成\(min(D,|D-d[i]|)\).假如这一个操作序列执行完了之后你的\(D\)变成\(0\)了,那么就称这个操作序列是合法的.现在有\(Q\)个询问,每个询问由一个\(q[i]\)表示,问你假如你可以把\(d[i]\)变成任意正整数,你能否将这个操作序列变成不合法的.\(N,Q\leqsl

AtCoder Regular Contest 101 F

题目链接:atcoder 考虑所有的洞将数轴划分成了若干个区间,则对每个机器人无论他怎么移动都不可能出这个区间,所以每个机器人至多只可能掉入两个洞中 对于最左边和最右边没有洞的机器人,显然他们的掉洞方案唯一,于是我们不去考虑它,对于剩下的机器人,我们用一个二元组\((l_i,r_i)\)表示它到离它最近的左/右边的洞的距离,很明显一个机器人掉入哪个洞只与操作序列达到的最左边/右边的位置有关. 将所有的二元组放在一个平面上,用它们来标记一些点,操作序列的历史达到的最左边/右边的位置可以用一条只会向

AtCoder Regular Contest 083 D:Restoring Road Network

In Takahashi Kingdom, which once existed, there are N cities, and some pairs of cities are connected bidirectionally by roads. The following are known about the road network: People traveled between cities only through roads. It was possible to reach