hdu1010 DFS和剪枝
2014-04-13 16:26
375 查看
不剪枝的话会超时。。
加上剪枝以后是这样的
感受了一下DFS
主要在 数据初始化 和 dot 加一那个地方检查了很久才发现。。。
方向数组只要四个方向走到了就可以 不用在意顺序 顺序有时候会影响执行时间 但总体上应该不会超时吧
参考PPT19页
参考博客
1 2 3 4
#include <iostream> #include <cmath> #include<cstdio> using namespace std; int N, M ,T; char map[10][10]; int dx,dy; bool can; int dir[4][2] = {{0,-1}, {0,1}, {1,0}, {-1,0} }; void dfs(int x,int y,int t) { //if(x < 0 || y< 0 || x >= N || y >= M)return;//越界则返回 也可以不判断 因为在进行dfs之前都确定了是不会越界的数 if(T == t && x == dx && y ==dy)//找到出口则返回 { can = true; return; } for(int i = 0;i < 4;i++)//四个方向分别进行搜索 { int a ,b; a = x + dir[i][0]; b = y + dir[i][1]; if(map[a][b] != 'X' && a>= 0 && a < N && b >= 0 && b < M)//这里已经判断了是否会越界 { map[a][b] = 'X';//把当前要走的下一个点标记为不可走的点 因为已经走过的点是不能在走的 dfs(a,b,t + 1);//按照dir中的方向继续递归下去 if(can)return;//找到出路了 map[a][b] = '.';//回朔回去 } } return; } int main() { int dot,sx,sy; // freopen("data.txt","r",stdin); // freopen("out.txt","w",stdout); while(cin>>N>>M>>T,N||M||T) { dot = 0; for(int i = 0; i < N; i++) for(int j = 0; j < M; j++) { cin>>map[i][j]; if(map[i][j] == 'S') { sx = i; sy = j; } else if(map[i][j] == 'D') { dx = i; dy = j; } else if(map[i][j] == '.')dot++; } if(T > dot) { cout<<"NO"<<endl; continue; } can = false;//对于很多数据的输入 最好不要在变量声明的时候付初值 经常忘了再新的测试数据前初始化。。。 map[sx][sy] = 'X';//从起点开始走 并把已经走过的起点标记为不可走 dfs(sx,sy,0);//走的步数t从0开始计数 if(can)cout<<"YES"<<endl; else cout<<"NO"<<endl; } // fclose(stdin); // fclose(stdout); return 0; }
加上剪枝以后是这样的
#include <iostream> #include <cmath> #include<cstdio> #include<cstdlib> using namespace std; int N, M ,T; char map[10][10]; int dx,dy; bool can; int dir[4][2] = {{0,-1}, {0,1}, {1,0}, {-1,0} }; void dfs(int x,int y,int t) { //if(x < 0 || y< 0 || x >= N || y >= M)return;//越界则返回 也可以不判断 因为在进行dfs之前都确定了是不会越界的数 if(T == t && x == dx && y ==dy)//找到出口则返回 { can = true; return; } //if((T -t) % 2 != (abs(dx - x) + abs(dy - y)) % 2)return; int tem ; tem = (T - t) - abs((dx - x)) - abs((dy - y));//剩余时间 减去还需要走的步数 不够的话肯定到不了 if(tem < 0 || tem % 2 != 0)return; //tem &1是奇偶判断 如果剩余时间 和要走的步数同奇偶的话 就有可能到达 //不同奇偶的话 一定到不了 可以参考下面的 ppt 就知道为什么了 //另外 a b同奇偶 则 a - b 比为偶数 否则为奇数 for(int i = 0;i < 4;i++)//四个方向分别进行搜索 { int a ,b; a = x + dir[i][0]; b = y + dir[i][1]; if(map[a][b] != 'X' && a>= 0 && a < N && b >= 0 && b < M)//这里已经判断了是否会越界 { map[a][b] = 'X';//把当前要走的下一个点标记为不可走的点 因为已经走过的点是不能在走的 dfs(a,b,t + 1);//按照dir中的方向继续递归下去 if(can)return;//找到出路了 map[a][b] = '.';//回朔回去 } } return; } int main() { int dot,sx,sy; // freopen("data.txt","r",stdin); // freopen("out.txt","w",stdout); while(cin>>N>>M>>T,N||M||T) { dot = 0; for(int i = 0; i < N; i++) for(int j = 0; j < M; j++) { cin>>map[i][j]; if(map[i][j] == 'S') { sx = i; sy = j; } else if(map[i][j] == 'D') { dx = i; dy = j; dot++;//忘了再这里加一 总是WA 哎 因为最后一个D 也要走一步才能到 } else if(map[i][j] == '.')dot++; } if(T > dot) { cout<<"NO"<<endl; continue; } can = false;//对于很多数据的输入 最好不要在变量声明的时候付初值 经常忘了再新的测试数据前初始化。。。 map[sx][sy] = 'X';//从起点开始走 并把已经走过的起点标记为不可走 dfs(sx,sy,0);//走的步数t从0开始计数 if(can) cout<<"YES"<<endl; else cout<<"NO"<<endl; } // fclose(stdin); // fclose(stdout); return 0; }
感受了一下DFS
主要在 数据初始化 和 dot 加一那个地方检查了很久才发现。。。
方向数组只要四个方向走到了就可以 不用在意顺序 顺序有时候会影响执行时间 但总体上应该不会超时吧
参考PPT19页
参考博客
1 2 3 4
相关文章推荐
- eclipse安装pydev不成功
- Leetcode_n-queens
- WM_CTLCOLOR消息
- Linux 下安装mysql
- 头指针,头结点,首元结点的区别,头结点的优点
- nyist 27 水池数目(dfs搜索)
- (传送门)Logistic regression (逻辑回归) 概述
- ArcGIS 10.1相关软件下载
- 操作系统---进程
- 【JAVA大数训练】N!
- 杭电2059龟兔赛跑
- C# Resources参数不支持重复项-Form拷贝出现的错误
- 第二章 栈和队列(1)——顺序存储
- Oracle,第六周
- 开发资源汇集
- webView中支持input的file的选择和alert弹出
- 简单排序:冒泡排序、选择排序和插入排序
- Java 8:ORM已经过时了
- 点亮数码管
- 录入本月取出上月的方法