ACM/ICPC 之 DFS范例(ZOJ2412-ZOJ1008)
通过几道例题简单阐述一下DFS的相关题型
ZOJ2412-Farm Irrigation
直观的DFS题型,稍加变化,记录好四个方向上的通路就能够做出来
题目和接水管类似,问最少要灌溉几次,即求解最少有多少个连通子图。
//和接水管游戏类似,将相应水管通路标记清晰即可
//Time:0Ms Memory:270K
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 55
#define OPPOSITE(x) ((x + 2) % 4) //x的相反位置
#define MAP(x,y) (map[x][y] - 'A') //水管序列
int row, col;
char map[MAX][MAX];
bool v[MAX][MAX];
int mov[][] = { {, }, {, }, {, -}, {-, } }; //东南西北
bool face[][] = { //face[i][j] : 在i方向上第j个水管是否有通路
{ ,,,,,,,,,, }, //东
{ ,,,,,,,,,, }, //南
{ ,,,,,,,,,, }, //西
{ ,,,,,,,,,, } //北
};
void dfs(int x,int y)
{
v[x][y] = true;
for (int i = ; i < ; i++)
{
int tx = x + mov[i][];
int ty = y + mov[i][];
if (face[i][MAP(x,y)] && tx >= && tx < row && ty >= && ty < col) //该水管相应对接方向有通路
{
if (!v[tx][ty] && face[OPPOSITE(i)][MAP(tx,ty)]) //对接水管相应方向有通路
dfs(tx, ty);
}
}
}
int main()
{
while (scanf("%d%d", &row, &col), row != - && col != -)
{
memset(v, false, sizeof(v));
for (int i = ; i < row; i++)
scanf("%s", map[i]);
int times = ;
for (int i = ; i < row; i++)
for (int j = ; j < col; j++)
{
if (!v[i][j]) {
times++;
dfs(i, j);
}
}
printf("%d\n", times);
}
return ;
}
ZOJ1008-Gnome Tetravex
看起来不像个搜索题,初看可能会以为需要枚举之类的,但是题中方块的各状态需要记录,在匹配失败时需要回退,因此是一道DFS题型。
大致的解题思路就是先枚举0行0列的方块,再依据此方块固定下一个方块,以此类推,出现不能匹配时回退。
虽然规模最大只有5,但是总方块数25个在DFS中也不可小觑,如果用纯DFS来做,时间度最坏可以达到O((n^2)!),因此剪枝或其他优化是必须的(只要数据不够水),我在超时后看了很多博客的解题报告(想不到了= =),就该题数据而言最好的优化方法是去重,即将相同方块合在一起,以减少DFS的分支数,但是我总觉得这么做挺奇怪的。。。虽然在大数据下,此题去重很有效果(数字在0-9,因此方块重复概率 < 1/2500),但是此题拿小数据故意出多组重复方块,不得不让人怀疑其心不善...
另外的剪枝方法,也有很多比较有效,但对此题没有太大帮助。
例如:记录各方向上各数字的个数,在匹配时动态增删,如果已经固定的方块需要的对应数字的数量缺失,那么就可以直接回退,剪枝效果在少量随机数据情况下比较好。
//去重就不会超时了,但这个优化实在是...让人感到很意外
//Time:2100ms Memory:272K
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; #define MAX 28 int n, m;
int sq[MAX][]; //上右下左
int board[MAX]; //棋盘上对应位置的square
int v[MAX]; //记录同类sq未被使用的数量 bool dfs(int num)
{
if (num == n*n)
return true;
//找出可以充当第num个方块的i方块
for (int i = ; i < m; i++)
{
if (!v[i]) continue; //没有未固定方块
if (num % n && sq[i][] != sq[board[num - ]][]) continue; //非第一列+不匹配
if (num / n && sq[i][] != sq[board[num - n]][]) continue; //非第一行+不匹配 v[i]--;
board[num] = i;
if (dfs(num + )) return true;
else v[i] ++;
}
return false;
} int main()
{
int t = ;
while (scanf("%d", &n), n)
{
if (t) printf("\n"); memset(v, , sizeof(v));
memset(board, , sizeof(board));
m = ;
for (int i = ; i < n*n; i++)
{
int u, r, d, l;
scanf("%d%d%d%d", &u, &r, &d, &l);
//查重
bool flag = false;
for (int j = ; j < m; j++)
{
if (u == sq[j][] && r == sq[j][] && d == sq[j][] && l == sq[j][])
{
v[j]++;
flag = true;
break;
}
}
if (!flag) {
sq[m][] = u; sq[m][] = r; sq[m][] = d; sq[m][] = l;
v[m++] ++;
}
} if (dfs()) printf("Game %d: Possible\n", ++t);
else printf("Game %d: Impossible\n", ++t);
} return ;
}
ACM/ICPC 之 DFS范例(ZOJ2412-ZOJ1008)的更多相关文章
- ACM/ICPC 之 DFS+SPFA-贪心+最短路(POJ2679)
//POJ2679 //DFS+SPFA+邻接表 //只能走每个点费用最小的边,相同则需保证距离最短 //求最小费用及最短距离 //Time:47Ms Memory:900K #include< ...
- ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)
判断是欧拉通路后,DFS简单剪枝求解字典序最小的欧拉通路路径 //Time:16Ms Memory:228K #include<iostream> #include<cstring& ...
- ACM/ICPC 之 DFS求解欧拉回路+打表(POJ1392)
本题可以通过全部n位二进制数作点,而后可按照某点A的末位数与某点B的首位数相等来建立A->B有向边,以此构图,改有向图则是一个有向欧拉回路,以下我利用DFS暴力求解该欧拉回路得到的字典序最小的路 ...
- ACM/ICPC 之 Floyd范例两道(POJ2570-POJ2263)
两道以Floyd算法为解法的范例,第二题如果数据量较大,须采用其他解法 POJ2570-Fiber Network //经典的传递闭包问题,由于只有26个公司可以采用二进制存储 //Time:141M ...
- ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))
两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法. ZOJ1586-QS Network 题意:见Code 题解:直接的MST ...
- ACM/ICPC 之 Kruskal范例(ZOJ1203-POJ1861(ZOJ1542))
两道最小生成树范例,Kruskal解法-以边为主体扩展最小生成树,需要利用并查集. ZOJ1203-Swordfish 题意:求n个给定平面坐标的城市中的一条平面距离上的最短路长(保留两位小数) 题解 ...
- ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)
两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory ...
- ACM/ICPC 之 BFS范例(ZOJ2913-ZOJ1136(POJ1465))
通过几道经典BFS例题阐述BFS思路 ZOJ2913-Bus Pass 题意:找一个center区域,使得center到所有公交线路最短,有等距的center则输出id最小的. 题解:经典的BFS,由 ...
- hduoj 4707 Pet 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4707 Pet Time Limit: 4000/2000 MS (Java/Others) Memory ...
随机推荐
- linux环境下给文件加密/解密的方法
原文地址:linix环境下给文件加密/解密的方法 作者:oracunix 一. 利用 vim/vi 加密:优点:加密后,如果不知道密码,就看不到明文,包括root用户也看不了:缺点:很明显让别人知 ...
- 获取C#代码执行的时间(精确到毫秒)
using System.Diagnostics;//引用相关的命名空间Stopwatch st=new Stopwatch ();//实例化类st. Start();//开始计时 //需要统计时间的 ...
- Unity相关路径
Application.dataPath 只读 在项目根目录下读取文件,但移动端没有访问权限.一般适用于PC端调试用. Application.streamingAssetsPath 在Assets目 ...
- 前端性能利器——dynatrace ajax edition
因为最近的工作跟性能分析有关系,所以写个小总结. 顺带推荐两个我常用的小工具: 1.文件对比工具beyond compare,非常好用,对比.修改很简单.当然我只是用的试用版本.google一下官网下 ...
- LYDSY模拟赛day3 序列
NOIP不考可持久,弃坑
- LYDSY模拟赛day3 涂色游戏
/* 非常好的题 */ #include <cstdio> #include <iostream> #include <cstdlib> #include < ...
- 网络编程2-UDP编程(DatagramSocket)
1.传输层有两个协议,一个是tcp协议,另一个是udp协议,tcp协议通过socket编程.udp通过数据报编程. UDP协议: (1)将数据.源地址.目的地址 封装成数据包,不需要建立链接 (2)每 ...
- WEB前端知识在乱花渐欲迷人眼的当下,如何分清主次和学习优先级呢?
从正美的吐槽开始,我回了下,说对盲目跟风的大众失去信心了.然后一些同学说我固步自封,另一些同学估计想说倚老卖老啥的.我想说清楚一点,我从 未停止过学习,只是对知识的重要程度和精力分配有自己的观点.具体 ...
- UIView动画效果
做出UI界面,实现程序功能,是重中之重,但是通过动画提升使用体验,一般人应该不会拒绝吧. 那么问题又来了,怎么做? 一: 稳扎稳打: 一步一步来吧,毕竟,心急吃不了热豆腐. 1.开启一个动画 2,设置 ...
- jquery版悬浮模块demo
在做在线客服时,代码就是按照该模块命名.现在,我要添加一个返回主页的功能,我觉得再复制一遍之前的代码,那个量有点多,如果我再添加一个功能,那个量会很多……现在我用创建对象字面量的方式来创建(其实我还想 ...