hdu1010 DFS和剪枝
来源:互联网 发布:大型网页游戏源码 编辑:程序博客网 时间:2024/04/30 01:38
不剪枝的话会超时。。
#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
0 0
- hdu1010 DFS和剪枝
- HDU1010-奇偶剪枝(DFS)
- hdu1010 dfs+路径剪枝
- hdu1010(dfs+剪枝)
- hdu1010 dfs奇偶剪枝
- HDU1010奇偶剪枝DFS
- hdu1010 dfs+剪枝
- HDU1010 DFS+奇偶剪枝
- dfs+剪枝(hdu1010)
- hdu1010 dfs+剪枝
- HDU1010 dfs奇偶剪枝
- HDU1010 DFS+奇偶剪枝
- hdu1010(dfs+剪枝)
- hdu1010(DFS + 奇偶剪枝)
- hdu1010(DFS+奇偶剪枝)
- hdu1010 (dfs+奇偶剪枝)
- hdu1010(dfs加剪枝)
- HDU1010 DFS+剪枝水题
- 小议MD5加密字符串的防破解技术
- UVa 712 - S-Trees
- Ajax编程技术
- maven简易教程
- 基于ssh的餐饮服务系统后台开发总结
- hdu1010 DFS和剪枝
- 感到
- 《推荐系统实践》学习笔记(二)
- Android开发
- 杭电 4500 小Q系列故事——屌丝的逆袭
- 杭电acm 1052
- php 乱码 iconv('UCS-2'
- 这个周末不轻松
- php curl与正则表达式抓取网页数据的例子