当时学的时候感觉打的挺溜,但现在看来全是在套模板,知识不复习,不重复,就很难长时间掌握。定期来看看吧!
深度优先搜素DFS
1、思路:它从某个状态开始,不断转移状态,直到无法转移,然后回退到上一状态,直到找到最终解。常用递归函数。
2、应用:解数独、走迷宫。
3、例题:
- 给定整数a1,a2,.....an,判断是否可以从中选出若干数,使它们的和恰好为k。
int a[maxn];
int n,k;
bool dfs(int i,int sum)
{
if(i==n) return sum==k;//前n项都计算完了,则返回判断sum与k是否相等
if(dfs(i+1,sum)) return true;
if(dfs(i+1,sum+a[i])) return true;
return false;
}
void solve()
{
if(dfs(0,0)) printf("Yes\n");
else printf("No\n");
}
- HDU1241 油井
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int dx[8]={1,-1,-1,1,1,0,-1,0};
int dy[8]={1,-1,1,-1,0,1,0,-1};
char a[105][105];
bool v[105][105];
int i,j,m,n,t;
void dfs(int x,int y)
{
if(v[x][y]) return ;
v[x][y]=true;
for(int k=0;k<8;k++)
{
int xx=x+dx[k];int yy=y+dy[k];
if(xx<0||yy<0||xx>=m||yy>=n) continue;
if(a[xx][yy]=='@'&&v[xx][yy]==false){
dfs(xx,yy);
}
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF&&(m+n!=0))
{
t=0;
memset(v,false,sizeof(v));
for(i=0;i<m;i++)
cin>>a[i];
for(i=0;i<m;i++){
for(j=0;j<n;j++){
if(a[i][j]=='@'&&v[i][j]==false){
t++;
dfs(i,j);
}
}
}
printf("%d\n",t);
}
return 0;
}
宽度优先搜索BFS
1、思路:先搜索距离初始状态近的状态。开始状态 ~只需转移一次 ~只需转移两次~~
2、利用队列,把从该状态可以转移到的尚未访问过的状态放入队列,如此往复,直到队列被取空或找到问题的解。
3、由近及远,容易用来求最短路径、最少操作。
4、用一个二维数组保存最短距离,也起到标记作用。INF常设为放大2~4倍。
5、例题
- 迷宫的最短路径POJ3984
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
typedef pair<int,int> p;
p x,y;
queue<p> q;
bool v[6][6];//标记
int b[6][6];//输入
p qian[6][6];//每个位置的前一个
stack<p> l; //保存最后路径
int dx[4]={-1,0,0,1};
int dy[4]={0,-1,1,0};
void print()
{
l.push(x);
while(x.first||x.second)
{
int i=x.first;
int j=x.second;
l.push(qian[i][j]);
//printf("%d %d\n",qian[xx][yy].first,qian[xx][yy].second);
x=qian[i][j];
}
while(!l.empty())
{
x=l.top();
printf("(%d, %d)\n",x.first,x.second);
l.pop();
}
return ;
}
void bfs(int a)
{
q.push(p(0,0));
v[0][0]=true;
qian[0][0].first=0;qian[0][0].second=0;
while(!q.empty())
{
x=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int xx=x.first+dx[i];int yy=x.second+dy[i];
if(xx<0||xx>=a||yy<0||yy>=a||v[xx][yy]) continue;
if(xx==a-1&&yy==a-1)
{
l.push(p(a-1,a-1));
print();return ;
}
if(b[xx][yy]==0)
{
q.push(p(xx,yy));
v[xx][yy]=true;
qian[xx][yy]=x;
}
}
}
}
int main()
{
int i,j;
memset(v,false,sizeof(v));
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
scanf("%d",&b[i][j]);
bfs(5);
return 0;
}