BZOJ3619 [Zjoi2014]璀灿光华 构造+dfs
题意:有一个$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的更多相关文章
- BZOJ3619 : [Zjoi2014]璀灿光华
终于把省选时的遗憾补上了… 对于构造立方体: 首先BFS构出底层,然后再逐层构造立方体 对于计算: $O(n^6)$爆搜即可. #include<cstdio> #include<c ...
- 题解:[ZJOI2014]璀灿光华
原题链接 OJ 题号 洛谷 3342 loj 2203 bzoj 3619 题目描述 金先生有一个女朋友没名字.她勤劳勇敢.智慧善良.金先生很喜欢她.为此,金先生用\(a^3\)块\(1 \times ...
- 「ZJOI2014」璀灿光华
「ZJOI2014」璀灿光华 实际上,可以不用建水晶立方体... 因为,发光水晶的方向都要枚举一遍. 只需知道发光水晶每个方向有哪些水晶就可以了. 对于一个发光水晶,将它连接的水晶标号. 从该水晶bf ...
- UVa 12118 nspector's Dilemma (构造+DFS+欧拉回路)
题意:给定n个点,e条边和每条边的长度t,每两个点之间都有路相连,让你求一条最短的路经过这e条边. 析:刚开始想到要判连通,然后把相应的几块加起来,但是,第二个样例就不过,后来一想,那么有欧拉回路的还 ...
- Codeforces 906B. Seating of Students(构造+DFS)
行和列>4的可以直接构造,只要交叉着放就好了,比如1 3 5 2 4和2 4 1 3 5,每一行和下一行用不同的方法就能保证没有邻居. 其他的可以用爆搜,每次暴力和后面的一个编号交换并判断可行性 ...
- 7.9 NOI模拟赛 A.图 构造 dfs树 二分图
啥都想不出来的我是不是废了/dk 这道题考的主要是构造 而我想的主要是乱搞. 一个很假很假的做法:直接暴力4种颜色染色 我也不知道对不对.. 不过成功的话一定是对的. 然后考虑奇环的问题 一个很假很假 ...
- 【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing
acm.hdu.edu.cn/showproblem.php?pid=6060 [题意] 给定一棵以1为根的树,把这颗树除1以外的结点划分为k个集合(可以有空集),把1加入划分后的集合 每个集合的结点 ...
- 【uva 1610】Party Games(算法效率--构造 dfs)
题意:有一个N个字符串(N≤1000,N为偶数)的集合,要求找一个长度最短的字符串(可不在集合内)S,使得集合中恰好一半的串小于等于S,另一半大于S.如果有多解,要求输出字典序最小的解. 解法:本来我 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- 【leetcode 简单】第二十七题 二叉树的最小深度
给定一个二叉树,找出其最小深度. 最小深度是从根节点到最近叶子节点的最短路径上的节点数量. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], ...
- # 2018高考&自主招生 - 游记
准备了一整个学期的高考和自主招生终于结束了....从育英出来, 以一个失败者的身份来写游记, 权当为明年的决战提供经验与总结. Day -1, June 5th 下午同学收拾考场, 自己在那里看书.. ...
- HNU Joke with permutation (深搜dfs)
题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=13341&courseid=0 Joke with pe ...
- Mysql储存过程6: in / out / inout
in 为向函数传送进去的值 out 为函数向外返回的值 intout 传送进去的值, 并且还返回这个值 )) begin then select 'true'; else select 'false' ...
- imperva系统升级遇见的错误(配置文件的导入导出)
今天心态有点炸了 今天去东兴证券做waf升级.浪费了两天才弄完.把客户都弄得有点急了.好歹原厂的工程师耐心的讲解这才弄完.感谢路哥.... 赶紧总结一下. 事情是这样的.东兴 证券的imperva是v ...
- 用C#实现对MSSqlServer数据库的增删改查---DAL层
说明:本人完成的工作是对传感器--超声波物位计进行硬件集成,上位机通过串口接收传感器数据并将其存到数据库中:在DAL层实现对数据库的增删改查,其中包含两个数据表分别是WaterLevelSet表和Wa ...
- puppet practice
目标 试验环境有两台主机(VM)构成,一台是master,一台是agent,完成以下工作: 新建用户newuser; 安装 ubuntu-cloud-keyring package,更改文件/etc/ ...
- VI编辑,配置文件
1,VI编辑 vi 分为3种模式 1>一般模式: [Ctrl + f ] 下一页 [Ctrl + b ] 上一页 [n+ enter] 向下移动n行 eg:2 ...
- [How to] HBase的bulkload使用方法
1.简介 将数据插入HBase表中的方法很多,我们可以通过TableOutputFormat以Mapreduce on HBase的方式将数据插入,也可以单纯的使用客户端API将数据插入.但是以上方法 ...
- PTP简介
PTP简介 在通信网络中,许多业务的正常运行都要求网络时钟同步,即整个网络各设备之间的时间或频率差保持在合理的误差水平内.网络时钟同步包括以下两个概念: l 时间同步:也叫相 ...