DFS(3)
来源:互联网 发布:js onmousemove 编辑:程序博客网 时间:2024/06/06 02:39
例题1:zjut 1398(全排列)http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1398
加入了剪枝,即在全排列中不能输出重复排列,还有就是需要排序
#include<iostream>#include<string>#include<cstdio>#include<algorithm>using namespace std;const int MAX=100;bool visit[MAX];string s,s1;string s2="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";void DFS(int cur) { int len=s.length(); if(cur==len) { for(int i=0;i<len;i++) cout<<s1[i]; cout<<endl; } else for(int i=0;i<len;++i) { if(!visit[i]) { if(i&&!visit[i-1]&&s[i]==s[i-1]) continue; visit[i]=true; s1[cur]=s[i]; DFS(cur+1); visit[i]=false; } }}int main(){ int n; cin>>n; getchar(); while(n--) { cin>>s; for(int i=0;i<s.length();i++) for(int j=i+1;j<s.length();j++) if(s2.find(s[i])>s2.find(s[j])) swap(s[i],s[j]); //排序 DFS(0); } return 0;}
这道题做完后可以做POJ 1256了~~
hdu 1241(以前是用BFS做的,现在用DFS做,发现还简单些,呵呵呵~~)题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241
#include<iostream>using namespace std;const int MAX=110;char map[MAX][MAX];int dx[8]={0,1,1,1,0,-1,-1,-1};//水平方向的坐标变化 int dy[8]={-1,-1,0,1,1,1,0,-1};//垂直方向的坐标变化 int n,m;int Inside(int x,int y){ return x>=0&&x<n&&y>=0&&y<m;}void DFS(int x,int y){ for(int i=0;i<8;i++) { int Newx=dx[i]+x; int Newy=dy[i]+y; if(Inside(Newx,Newy)&&map[Newx][Newy]=='@')//要保证在范围内 { map[Newx][Newy]='*';//要调整过来,搜过了的可以用@外的任意字符代替 DFS(Newx,Newy); } }}int main(){ while(cin>>n>>m&&m||n) { int step=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>map[i][j]; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(map[i][j]=='@') { step++; DFS(i,j); } cout<<step<<endl; } return 0;}
例题3:nyist 325 (zb的生日)题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=325
//abs(a-b)=abs((sum-b)-b)=abs(sum-2*b),所以只需搜其中一个人的即可,用甲乙表示~ #include<iostream>#include<cstdlib>using namespace std;int a[25];int Max,sum; void DFS(int cur,int m)//cur是用来保存其中一人的西瓜重量~,用甲表示 { if(m<0) return ; if(Max>abs(sum-2*cur)) Max=abs(sum-2*cur); DFS(cur+a[m],m-1); //甲要a[m]这个西瓜,则甲的西瓜重量+a[m],搜索下一个西瓜。 DFS(cur,m-1); //甲不要这个西瓜m则直接搜索下一个西瓜。 } int main(){ int n; while(cin>>n) { sum=0; Max=1000000000; for(int i=0;i<n;i++) { cin>>a[i]; sum+=a[i]; } DFS(0,n-1); cout<<Max<<endl; } return 0;}
例题4:hdu 1010题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
知识点:奇偶剪枝
把矩阵看成如下形式:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从为 0 的格子走一步,必然走向为 1 的格子 。
从为 1 的格子走一步,必然走向为 0 的格子 。
即:
从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。
所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达!
#include<iostream>#include<cstring>using namespace std;int dx[4]={0,1,0,-1},dy[4]={-1,0,1,0};char map[7][7];int M,N,T,flag,ex,ey;int Inside(int x,int y){ return x>=0&&x<N&&y>=0&&y<M;}void DFS(int x,int y,int cur){ if(x==ex&&y==ey&&cur==T) flag=1; if(cur>T||flag) return ; if(T-cur<abs(ex-x)+abs(ey-y)) return ;//剩余时间小于理论值 if((T-cur)%2!=(abs(ex-x)+abs(ey-y))%2) return ;//奇偶剪枝!! for(int i=0;i<4;i++) { int Newx=dx[i]+x; int Newy=dy[i]+y; if(Inside(Newx,Newy)&&map[Newx][Newy]!='X') { map[Newx][Newy]='X'; DFS(Newx,Newy,cur+1); map[Newx][Newy]='.';//回溯~~~ } } }int main(){ int sx,sy; while(cin>>N>>M>>T&&N||M||T) { int num=0; for(int i=0;i<N;i++) for(int j=0;j<M;j++) { cin>>map[i][j]; if(map[i][j]!='X') num++; if(map[i][j]=='S') sx=i,sy=j; if(map[i][j]=='D') ex=i,ey=j; } map[sx][sy]='X'; if(num<T) puts("NO"); else { flag=0; DFS(sx,sy,0); if(flag) puts("YES"); else puts("NO"); } } return 0;}
例题5:hdu 1181题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1181
深度遍历,首字母为b,直到字符串的最后一个字母为m停止,主要是注意输入。。。。得看清楚题目
#include<iostream>#include<string>using namespace std;string s[105],s1;int num,flag;bool visit[105];void DFS(char c){ if(c=='m') flag=1; if(flag) return ; else for(int i=0;i<num;i++) if(!visit[i]&&s[i][0]==c) { visit[i]=true; int len=s[i].length(); DFS(s[i][len-1]); visit[i]=false; }}int main(){ num=0; while(cin>>s1) { s[num++]=s1; if(s1=="0") { flag=0; for(int i=0;i<num;i++) { if(s[i][0]=='b') { memset(visit,false,sizeof(visit)); DFS('b'); if(flag) cout<<"Yes."<<endl; } if(flag) break; } if(!flag) cout<<"No."<<endl; num=0;//开始看错了题目,输入一直感觉不对劲,原来它是以0作为一组字符串结束,可能还会输入下一组,所以num=0; } } return 0;}
例题6:nyist 82(迷宫寻宝一)题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=82
分析:深搜问题,当然可以用广搜,就是要求稍微复杂点,昨天晚上RE了一页,郁闷,直到刚刚才做出来,比方说一个图,每个门的钥匙个数各不相同,我们要开这个门的话就要求找到这个门的所有钥匙,下面的代码中用Key[]保存开每扇门的所需的钥匙数,当然这个不一定需要开所有的门,只要开了某扇门后能够找到出口即可,具体看代码,写的比较的乱~~~
#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int MAX=25;#define CLR(arr,val) memset(arr,val,sizeof(arr))int n,m,flag,Startx,Starty,Endx,Endy;int visit[5],num[5],Key[5];int dx[4]={0,1,0,-1},dy[4]={-1,0,1,0};char map[MAX][MAX];struct point{point(){px=-1;py=-1;}point(int x,int y):px(x),py(y){} int px,py;}D[5];int Inside(int x,int y){ return x>=0&&x<n&&y>=0&&y<m;}void DFS(int x,int y){ if(x==Endx&&y==Endy) flag=1; if(flag) return ;for(int i=0;i<4;i++){ int Newx=x+dx[i]; int Newy=y+dy[i]; char c=map[Newx][Newy];if(c!='X'&&Inside(Newx,Newy)){ if(c>='A'&&c<='E'){ visit[c-'A']=1;//记录该扇门是否出现过 D[c-'A'].px=Newx,D[c-'A'].py=Newy;//记录该扇门的位置if(num[c-'A']!=Key[c-'A']) continue ;//若是不满足找到的钥匙的个数等于需要的钥匙数则不进行深搜}if(c>='a'&&c<='e') { num[c-'a']++; if(visit[c-'a']&&num[c-'a']==Key[c-'a']) DFS(D[c-'a'].px,D[c-'a'].py);//前提是这扇门已经被访问过} map[Newx][Newy]='X';//不需回溯,因为要找钥匙DFS(Newx,Newy);}}}int main(){ int i,j;while(cin>>n>>m&&n||m){ flag=0; CLR(Key,0); CLR(num,0);CLR(visit,0);for(i=0;i<n;i++) cin>>map[i]; for(i=0;i<n;i++)for(j=0;j<m;j++){ char c=map[i][j]; if(c=='S') Startx=i,Starty=j; if(c=='G') Endx=i,Endy=j; if(c>='a'&&c<='e') Key[c-'a']++;} DFS(Startx,Starty);if(flag) cout<<"YES"<<endl;else cout<<"NO"<<endl;} return 0;}
- DFS(3)
- dfs 2016.5.3
- DFS
- DFS
- dfs
- dfs
- dfs
- dfs
- DFS
- DFS
- dfs
- DFS
- DFS
- DFS
- dfs
- DFS
- dfs
- dfs
- open fetion和hybrid
- C++实现爱拉托斯散筛法寻找素数
- Android开发的技术层次
- C#之DataSet类
- IOCP知识点及疑惑
- DFS(3)
- Android音频焦点
- 红黑树
- 八款开源 Android 游戏引擎
- Java how to program(4th)中的专业词汇ch10
- 杨毅:不够优秀就不要腆着脸继续占便宜
- java: cannot execute binary file问题的解决
- c primer plus(第五版)中文版 第五章 编程练习
- poj 1010 邮票问题 DFS