题意:有一个$a^3$个小正方体组成的大正方体,其中有n个正方体会向上下左右前后六个方向中的一个发出光,正方体是透光的,被照亮的正方体有个美丽值$g_{i}$,给出正方体的相邻关系,问美丽值之和的最小值和最大值。

难点在如何建图。

先随便找个棱角,再随便建两条棱,然后一层一层铺下去。当铺到一个新的点时,肯定已经铺好了至少一个与它相邻的点,然后再暴力算出已知与当前点相邻的点给出的每个相邻的点的出现次数,然后没被填过且出现次数最多的那个点的编号,就是当前点的编号。

建完图跑个dfs就行了。

#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long long
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,k) for (register int i=first[k];i;i=last[i])
char c;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
c=ch;return x*f;
}
const int N = 70*70*70+10;
const int dx[6]={1,-1,0,0,0,0};
const int dy[6]={0,0,1,-1,0,0};
const int dz[6]={0,0,0,0,1,-1};
struct node{
int x,y,z;
}l[11];
int n,rt,tot,g[N],next[N][7],a[75][75][75],vis[N],cnt[N];
ll Max,Min;
inline bool check(int x,int y,int z){return x>0&&x<=n&&y>0&&y<=n&&z>0&&z<=n;}
inline void dfs(int now,int x,int y,int z,int k){
a[x][y][z]=now,vis[now]=1;
if (z==n&&k==4||y==n&&k==2) return;
if (z==n-1&&k==4||y==n-1&&k==2){
For(i,1,next[now][0]){
int v=next[now][i];
if (!vis[v]&&next[v][0]==3){dfs(v,x+dx[k],y+dy[k],z+dz[k],k);break;}
}
return;
}
For(i,1,next[now][0]){
int v=next[now][i];
if (!vis[v]&&next[v][0]==4){dfs(v,x+dx[k],y+dy[k],z+dz[k],k);break;}
}
}
int x,y,z,Vis[75][75][75];
ll ans;
inline ll min(ll a,ll b){return a<b?a:b;}
inline ll max(ll a,ll b){return a>b?a:b;}
inline void dfs(int k){
if (k>tot){Max=max(Max,ans),Min=min(Min,ans);return;}
For(i,0,5){
x=l[k].x,y=l[k].y,z=l[k].z;
while (check(x+dx[i],y+dy[i],z+dz[i])){
x+=dx[i],y+=dy[i],z+=dz[i];
if (!Vis[x][y][z]) ans+=1ll*g[a[x][y][z]];Vis[x][y][z]++;
}
dfs(k+1);
x=l[k].x,y=l[k].y,z=l[k].z;
while (check(x+dx[i],y+dy[i],z+dz[i])){
x+=dx[i],y+=dy[i],z+=dz[i],Vis[x][y][z]--;
if (!Vis[x][y][z]) ans-=1ll*g[a[x][y][z]];
}
}
}
inline void Print(){
For(i,1,n){
For(j,1,n){
For(k,1,n) printf("%d ",a[i][j][k]);puts("");
}puts("");
}
}
int main(){
//freopen("P3342.in","r",stdin);
//freopen("P3342.out","w",stdout);
n=read();
For(i,1,n*n*n){
g[i]=read();
while (c==' ') next[i][++next[i][0]]=read();
}
For(i,1,n*n*n) if (next[i][0]==3){rt=i;break;}
dfs(rt,1,1,1,4),dfs(rt,1,1,1,2);
For(i,1,n) For(j,1,n) For(k,1,n){
if (a[i][j][k]) continue;
int Max=0,Max_id=0;
for (int d=0;d<6;d+=2){
int v=a[i-dx[d]][j-dy[d]][k-dz[d]];
For(nxt,1,next[v][0]){
cnt[next[v][nxt]]++;
if (cnt[next[v][nxt]]>Max&&!vis[next[v][nxt]]) Max=cnt[next[v][nxt]],Max_id=next[v][nxt];
}
}
a[i][j][k]=Max_id,vis[Max_id]=1;
for (int d=0;d<6;d+=2){
int v=a[i-dx[d]][j-dy[d]][k-dz[d]];
For(nxt,1,next[v][0]) cnt[next[v][nxt]]--;
}
}
For(i,1,n) For(j,1,n) For(k,1,n) if (!g[a[i][j][k]]) l[++tot]=(node){i,j,k};
Max=(ll)-1e18,Min=-Max;
dfs(1);
printf("%lld %lld",Min,Max);
}

BZOJ3619 [Zjoi2014]璀灿光华 构造+dfs的更多相关文章

  1. BZOJ3619 : [Zjoi2014]璀灿光华

    终于把省选时的遗憾补上了… 对于构造立方体: 首先BFS构出底层,然后再逐层构造立方体 对于计算: $O(n^6)$爆搜即可. #include<cstdio> #include<c ...

  2. 题解:[ZJOI2014]璀灿光华

    原题链接 OJ 题号 洛谷 3342 loj 2203 bzoj 3619 题目描述 金先生有一个女朋友没名字.她勤劳勇敢.智慧善良.金先生很喜欢她.为此,金先生用\(a^3\)块\(1 \times ...

  3. 「ZJOI2014」璀灿光华

    「ZJOI2014」璀灿光华 实际上,可以不用建水晶立方体... 因为,发光水晶的方向都要枚举一遍. 只需知道发光水晶每个方向有哪些水晶就可以了. 对于一个发光水晶,将它连接的水晶标号. 从该水晶bf ...

  4. UVa 12118 nspector's Dilemma (构造+DFS+欧拉回路)

    题意:给定n个点,e条边和每条边的长度t,每两个点之间都有路相连,让你求一条最短的路经过这e条边. 析:刚开始想到要判连通,然后把相应的几块加起来,但是,第二个样例就不过,后来一想,那么有欧拉回路的还 ...

  5. Codeforces 906B. Seating of Students(构造+DFS)

    行和列>4的可以直接构造,只要交叉着放就好了,比如1 3 5 2 4和2 4 1 3 5,每一行和下一行用不同的方法就能保证没有邻居. 其他的可以用爆搜,每次暴力和后面的一个编号交换并判断可行性 ...

  6. 7.9 NOI模拟赛 A.图 构造 dfs树 二分图

    啥都想不出来的我是不是废了/dk 这道题考的主要是构造 而我想的主要是乱搞. 一个很假很假的做法:直接暴力4种颜色染色 我也不知道对不对.. 不过成功的话一定是对的. 然后考虑奇环的问题 一个很假很假 ...

  7. 【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing

    acm.hdu.edu.cn/showproblem.php?pid=6060 [题意] 给定一棵以1为根的树,把这颗树除1以外的结点划分为k个集合(可以有空集),把1加入划分后的集合 每个集合的结点 ...

  8. 【uva 1610】Party Games(算法效率--构造 dfs)

    题意:有一个N个字符串(N≤1000,N为偶数)的集合,要求找一个长度最短的字符串(可不在集合内)S,使得集合中恰好一半的串小于等于S,另一半大于S.如果有多解,要求输出字典序最小的解. 解法:本来我 ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. How to reset XiaoMi bluetooth headphone Youth edition.

    To reset the speaker 1. Long press the phone call button to shut off the speaker 2. Connect the char ...

  2. python之自然语言处理入门(一)

    前言 NTLK是著名的Python自然语言处理工具包,记录一下学习NTLK的总结. 安装nltk pip install nltk # 测试 import nltk 安装相关的包 import nlt ...

  3. 74.VS2013和opencv3.1.0安装教程

    一.先下载文件 1.VS2013 VS2013有很多版本,专业版,旗舰版,中文英文之类的,所对应的密钥也不一样.我选择的是简体中文专业版.下载链接如下. http://www.musnow.com/t ...

  4. Linux内核中的队列 kfifo【转】

    转自:http://airekans.github.io/c/2015/10/12/linux-kernel-data-structure-kfifo#api 在内核中经常会有需要用到队列来传递数据的 ...

  5. Loadrunner脚本学习总结

    1.1      web脚本录制选择Web(HTTP/HTML)协议: 注意录制脚本前选择如下协议: 1.2      脚本如果需要使用如下函数: web_reg_save_param.web_fin ...

  6. oracle只要第一条数据SQL

    select * from ( select * from COMMON_BIZREL_WF where sponsor is not null order by serialid ) where r ...

  7. Webcollector应用(二)

    先吐槽一句哀家的人品,总在写好代码之后,网站默默的升级,没有一点点防备... 一.加代理 爬取一个网站的时候,爬了不到一半,IP被封了,整个内部局域网的所有电脑都不能访问网站了. public cla ...

  8. NOIP填坑计划

    斗地主 华容道 开车旅行 疫情控制 飞扬的小鸟 Mayan游戏 天天爱跑步

  9. xpath简单应用

    相对路径与绝对路径: 如果"/"处在XPath表达式开头则表示文档根元素,(表达式中间作为分隔符用以分割每一个步进表达式)如:/messages/message/subject是一 ...

  10. XSS与CSRF两种跨站攻击总结

    在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了.但是 ...