dfs算法是深度搜索算法。从某一节点开始遍历直至到路径底部,如果不是所寻找的,则回溯到上个节点后,再遍历其他路径。不断重复这个过程。一般此过程消耗很大,需要一些优化才能保持算法的高效。
hdu1010:(奇偶剪枝)
主要题意是一只小狗为了一块骨头,然后进入迷宫。当它拿起骨头的时候,迷宫开始下沉。小狗才发这迷宫是个陷阱。这迷宫只有一个门,小狗只能在规定时间内跑到到门这里才能顺利出逃。另外,小狗每跑过一块,该块就会下沉。因此不能过早或者过晚到门。(题目挺有意思)
刚开始刷题时,没有用剪枝,超时了。使用奇偶剪枝+dfs后,可以直接过。奇偶剪枝的内容可以百度。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; /* 'X': a block of wall, which the doggie cannot enter; 'S': the start point of the doggie; 'D': the Door; '.': an empty block. */ int n,m,t; bool flag = false; int doorI,doorJ; char blocks[7][8]; bool isEnd(int curI,int curJ,int curT) { if(flag) return true; if(curT > t) return true; if(curT == t) { if(curI == doorI && curJ == doorJ) flag = true; return true; } if(curI < 0 || curJ < 0 || curI >= n || curJ >=m) return true; if(blocks[curI][curJ] == 'X') return true; if(curI==doorI && curJ == doorJ) return true; return false; } void dfs(int curI,int curJ,int curT) { if(isEnd(curI,curJ,curT)) return; char temp = blocks[curI][curJ]; blocks[curI][curJ] = 'X'; dfs(curI-1,curJ,curT+1); dfs(curI+1,curJ,curT+1); dfs(curI,curJ-1,curT+1); dfs(curI,curJ+1,curT+1); blocks[curI][curJ] = temp; } int main() { while(~scanf("%d%d%d",&n,&m,&t),n&&m&&t) { flag = false; int startI=0,startJ=0; for(int i=0;i<n;++i) { scanf("%s",blocks[i]); for(int j=0;j<m;++j) if(blocks[i][j]=='S') startI = i,startJ = j; else if(blocks[i][j]=='D') doorI = i,doorJ = j; } //ΌτΦ¦ if(abs(startI-doorI)+abs(startJ-doorJ)> t ||(startI + startJ + doorI + doorJ + t)%2) { printf("NO\n"); continue; } dfs(startI,startJ,0); if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
hdu2553:(简单题)
N皇后问题,使用dfs一次性把1到10的值算出来,然后直接输出Hash[n]就行了,否则会超时。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int cnt; int n; //n不大于10 int f[10]; int Hash[11]; bool isEnd(int curI) { for(int i=0;i<curI-1;++i) if(f[curI-1]==f[i]|| f[curI-1]-f[i]==curI-i-1|| f[i]-f[curI-1]==curI-i-1) return true; if(curI == n) { ++cnt; //注释的是输出代码,可以打开注释,看具体的输出 /*for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { if(f[i] == j) printf("1 "); else printf("0 "); } printf("\n"); } printf("\n"); */ return true; } return false; } void dfs(int curI) { if(isEnd(curI)) return; for(int j=0;j<n;++j) { f[curI] = j; dfs(curI+1); } } int main() { for(n=1;n<=10;++n) { cnt = 0; memset(f,0,sizeof(0)); dfs(0); Hash[n] = cnt; } while(~scanf("%d",&n),n) { printf("%d\n",Hash[n]); } return 0; }