problem

luogu-P3342

solution

你感觉这道题没考什么,又感觉考了什么

通过样例以及题面,我们并未获取到『立方体每个小方块的编号是按一定规则命名』的信息。

也就是说,我们需要通过输入的每个小方块相邻的编号的信息来建出这个立方体的坐标系。

我的做法较暴力但不用思考太多,简单易上手。你值得拥有

  • 首先,我们先随便找一个三度点(只有三个水晶和该水晶有公共面),钦定为 (1,1,1)(1,1,1)(1,1,1)。

    然后以这个点 bfs\text{bfs}bfs 搜,得到每个点的距离,我们记为 dis0dis_0dis0​。

  • 其次,我们再随便找一个与上一个点距离恰好为 2n−22n-22n−2 的点,即 dis0(i)=2n−2dis_0(i)=2n-2dis0​(i)=2n−2,钦定为 (n,n,1)(n,n,1)(n,n,1)。

    然后以这个点 bfs\text{bfs}bfs 搜,得到每个点的距离,我们记为 dis1dis_1dis1​。

  • 接着,我们仍随便找一个与上两个点距离恰都为 n−1n-1n−1 的点,即 dis0(i)=dis1(i)=n−1dis_0(i)=dis_1(i)=n-1dis0​(i)=dis1​(i)=n−1,钦定为 (n,1,1)(n,1,1)(n,1,1)。

    然后以这个点 bfs\text{bfs}bfs 搜,得到每个点的距离,我们记为 dis2dis_2dis2​。

这里的距离指的是曼哈顿距离 x,y,zx,y,zx,y,z 三维坐标差的绝对值之和。

考虑小方块 iii 的距离信息点对 (dis1(i)−dis0(i),dis2(i)−dis0(i))\Big(dis_1(i)-dis_0(i),dis_2(i)-dis_0(i)\Big)(dis1​(i)−dis0​(i),dis2​(i)−dis0​(i))。

observation1:\text{observation1}:observation1: 该点对与 iii 的真正的 zzz 坐标无关。

observation2:\text{observation2}:observation2: 该点对与小方块的真正 (x,y)(x,y)(x,y) 坐标存在一一对应关系。这只能自己臆想了

而 dis0(i)=(x,y,z)↔(1,1,1)dis_0(i)=(x,y,z)\leftrightarrow (1,1,1)dis0​(i)=(x,y,z)↔(1,1,1),所以我们可以选择通过 dis0(i)dis_0(i)dis0​(i) 与已经求出的 x,yx,yx,y 来推出小方块的 zzz 坐标。

最后只用 dfs\text{dfs}dfs 暴搜枚举每个特殊发光小水晶扩散的方向,O(6n)O(6^n)O(6n)。

然后 check\text{check}check 沿着该方向枚举一路上的水晶,用 visvisvis 标记是否已经访问过了,非第一次访问不计入发光贡献。

最后清空 vis\text{vis}vis 数组,也是按照方向清空。不然就是 O(a3)O(a^3)O(a3) 的复杂度了。

时间复杂度 O(6na)O(6^na)O(6na)。

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 400000
#define MAX 150
struct node { int x, y, z; }pos[MAX << 2][MAX << 2];
vector < int > G[maxn];
vector < node > NB;
int g[maxn], dir[maxn];
int dis[3][maxn];
int vis[MAX][MAX][MAX], val[MAX][MAX][MAX];
int Min = 1e9, Max = -1e9, n, m;
queue < int > q;void bfs( int s, int *dis ) {dis[s] = 0; q.push( s );while( ! q.empty() ) {int u = q.front(); q.pop();for( int v : G[u] ) if( dis[v] > dis[u] + 1 ) dis[v] = dis[u] + 1, q.push( v );}
}void calc() {int sum = 0;for( int k = 0;k < NB.size();k ++ ) {int x = NB[k].x, y = NB[k].y, z = NB[k].z;switch( dir[k] ) {case 0 : {for( int i = 1;i <= x;i ++ )if( ! vis[i][y][z] )vis[i][y][z] = 1, sum += val[i][y][z];break;}case 1 : {for( int i = x;i <= n;i ++ )if( ! vis[i][y][z] )vis[i][y][z] = 1, sum += val[i][y][z];break;}case 2 : {for( int i = 1;i <= y;i ++ )if( ! vis[x][i][z] )vis[x][i][z] = 1, sum += val[x][i][z];break;}case 3 : {for( int i = y;i <= n;i ++ )if( ! vis[x][i][z] )vis[x][i][z] = 1, sum += val[x][i][z];break;}case 4 : {for( int i = 1;i <= z;i ++ )if( ! vis[x][y][i] )vis[x][y][i] = 1, sum += val[x][y][i];break;}case 5 : {for( int i = z;i <= n;i ++ )if( ! vis[x][y][i] )vis[x][y][i] = 1, sum += val[x][y][i];break;}}}Min = min( Min, sum ), Max = max( Max, sum );for( int k = 0;k < NB.size();k ++ ) {int x = NB[k].x, y = NB[k].y, z = NB[k].z;switch( dir[k] ) {case 0 : for( int i = 1;i <= x;i ++ ) vis[i][y][z] = 0; break;case 1 : for( int i = x;i <= n;i ++ ) vis[i][y][z] = 0; break;case 2 : for( int i = 1;i <= y;i ++ ) vis[x][i][z] = 0; break;case 3 : for( int i = y;i <= n;i ++ ) vis[x][i][z] = 0; break;case 4 : for( int i = 1;i <= z;i ++ ) vis[x][y][i] = 0; break;case 5 : for( int i = z;i <= n;i ++ ) vis[x][y][i] = 0; break;}}
}void dfs( int x ) {if( x == NB.size() ) return calc(), void();for( int i = 0;i < 6;i ++ ) dir[x] = i, dfs( x + 1 );
}int CalcDis( int x, int y, int a, int b ) { return fabs( x - a ) + fabs( y - b ); }int main() {memset( dis, 0x3f, sizeof( dis ) );scanf( "%d", &n );m = n * n * n;for( int i = 1, id;i <= m;i ++ ) {scanf( "%d", &g[i] );do { scanf( "%d", &id ), G[i].push_back( id ); } while( getchar() != '\n' );}int p1, p2, p3;for( int i = 1;i <= m;i ++ ) if( G[i].size() == 3 ) p1 = i;val[1][1][1] = g[p1]; bfs( p1, dis[0] );for( int i = 1;i <= m;i ++ ) if( G[i].size() == 3 and dis[0][i] == (n - 1 << 1) ) p2 = i;val[n][n][1] = g[p2]; bfs( p2, dis[1] );for( int i = 1;i <= m;i ++ ) if( G[i].size() == 3 and dis[0][i] == n - 1 and dis[1][i] == n - 1 ) p3 = i;val[n][1][1] = g[p3]; bfs( p3, dis[2] );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ ) {int d0 = CalcDis( 1, 1, i, j );int d1 = CalcDis( n, n, i, j );int d2 = CalcDis( n, 1, i, j );pos[MAX + d1 - d0][MAX + d2 - d0] = { i, j, 1 };}for( int i = 1;i <= m;i ++ ) {node p = pos[MAX + dis[1][i] - dis[0][i]][MAX + dis[2][i] - dis[0][i]];p.z = dis[0][i] - CalcDis( 1, 1, p.x, p.y ) + 1;val[p.x][p.y][p.z] = g[i];if( ! g[i] ) NB.push_back( p );}dfs( 0 );printf( "%d %d\n", Min, Max );return 0;
}

[ZJOI2014] 璀璨光华(bfs建图 + dfs搜索)相关推荐

  1. 链式前向星模板 建图+dfs+bfs+dijkstra

    边没有用struct封装起来,节点和边的计数起点如果不符合习惯可以稍作修改 建图+DFS+BFS #include <cstdio> #include <cstring> #i ...

  2. vector邻接表建图+DFS+BFS

    以边操作为主的图用边集数组存储比较好,相比链式前向星,vector建图更容易懂. #include <iostream> #include <cstdio> #include ...

  3. hdu 1044 BFS(压缩图)+DFS

    题意:              给你起点,终点,图上有墙有路还有宝物,问你在规定时间内能否能到终点,如果能问最多能捡到多少宝物. 思路:           看完这个题目果断 BFS+三维的mark ...

  4. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

  5. POJ2195费用流+BFS建图

    题意:       给你一个n*m的地图,上面有w个人,和w个房子,每个人都要进房子,每个房子只能进一个人,问所有人都进房子的路径总和最少是多少? 思路:       比较简单的最大流,直接建立两排, ...

  6. hdu 4568 Hunter bfs建图+TSP状压DP

    想AC的人请跳过这一段... 题目应该都能读懂.但是个人觉得这题出的很烂,意思太模糊了. 首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手. 因为我想到了这几 ...

  7. Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)

    对算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)用Java实现其中的伪代码算法,案例也采用算法导论中的图. import java.util.ArrayList; import java ...

  8. 【DFS反向建图记忆化搜索】UPC Contest2592 - 2020年秋季组队训练赛第十四场 问题 D: Mysterious Treasure

    问题 D: Mysterious Treasure 时间限制: 1 Sec 内存限制: 128 MB 题目描述 WNJXYK and DIDIDI is playing a game. DIDIDI ...

  9. 图的遍历(C语言,邻接表存储的图 - DFS,邻接矩阵存储的图 - BFS)

    邻接表存储的图 - DFS /* 邻接表存储的图 - DFS */void Visit( Vertex V ) {printf("正在访问顶点%d\n", V); }/* Visi ...

最新文章

  1. Gartner:预计2018年人工智能行业总价值达1.2万亿美元
  2. 机器人滚边有波浪_汽车开启件机器人滚边缺陷分析与调整
  3. 以太网数据包、IP包、TCP/UDP 包的结构(转)
  4. MFC对话框控件成员变量编程熟悉 - 开发一个简单天线长度计算器
  5. mysql性能优化教程_mysql性能优化教程
  6. Matlab:绘制简单能量的接收机工作特性曲线(Energy_detection_simulation_ok)
  7. SpringCloud(若依微服务版)读取Nacos中的配置以及多个服务共享Nacos配置的使用
  8. 一生只有43年,喜欢泡妹打架,却凭借一篇文章震惊世界,跻身一流数学家
  9. App Engine中的Google Services身份验证,第1部分
  10. printf 打印 文件名 函数名 行号
  11. APACHE ACTIVEMQ安装
  12. CS231N课程笔记学习一——图像分类
  13. Python源码剖析-深度探索动态语言核心技术
  14. 高一计算机网络技术应用计划,高一信息技术课教学计划
  15. 金庸年度最新十大广告
  16. composer 安装php 扩展,composer 服务器安装扩展失败怎么办
  17. LaTeX中的参考文献——作者年代引用
  18. 纯css饼图,使用css3画饼图
  19. 微信小程序云开发体会——总结软件工程导论大作业
  20. 信息安全实训笔记1——身份认证技术

热门文章

  1. python如何退出命令行_如何退出python命令行
  2. linux配置ip地址 routes,CentOS 7 设置网络IP地址(示例代码)
  3. html游戏怎么做,HTML5 制做“游戏”的一个基本流程
  4. oracle 有计划任务吗,oracle计划任务的问题
  5. php链表和联表的区别,PHP_浅谈PHP链表数据结构(单链表),链表:是一个有序的列表,但 - phpStudy...
  6. 算法题目——使用最小花费爬楼梯(动态规划)
  7. [计组]寄存器和存储器的区别
  8. C++文本文件操作和二进制文件读写
  9. [蓝桥杯][历届试题]网络寻路-dfs,图的遍历
  10. 蓝桥杯2015初赛-星系炸弹-日期计算