ACM第二专题—搜索总结

概述:搜索分为广度优先搜索(BFS)和深度优先搜索(DFS)两类,前者用队列实现,后者用递归实现,后者用于列举所有可能情况,前者用于求最短路径。可以用二分搜索和三分搜索解决一些比较简单的搜索问题。

例题:

1.求连通块(DFS)

部分代码:

void dfs(int r,int c,int id)
{
    if(r<0||r>=m||c<0||c>=n)
        return;
    if(idx[r][c]>0||tu[r][c]!='W')
        return;
    idx[r][c]=id;
    for(int dr=-1; dr<=1; dr++)   
        for(int dc=-1; dc<=1; dc++)  
            if(dr!=0||dc!=0)
                dfs(r+dr,c+dc,id);
}
用二重循环来找到当前格子相邻的八个格子,其实也可以用常量数组或者写八个DFS。
2.迷宫问题(BFS)

部分代码:

void bfs(int x,int y){

queue<int>q;//BFS搜索用队列实现

int d,u=0;

vis[x][y]=1; q.push(u); while(q.size()!=0){

u=q.front();//u和下面的临时变量v的作用是将二维图转化为一维数列存储

//该方法可以避开另建立结构体记录横座标值和纵座标值

//例如u=20即代表着第四行(从零算起)第零列的位置

//其中转化方法为下面两句

 q.pop();//从队头拿出一个数

x=u/5; //除以列数,及得到第几行  

y=u%5; //对列数取模,记得到列数

for(int i=0;i<4;i++){//上下左右查找

int nx = x+dir[i][0],

ny = y+dir[i][1];

 if(nx>=0&&nx<=4&&ny>=0&&ny<=4&&!maze[nx][ny]&&!vis[nx][ny]){

int v = nx*5+ny;

q.push(v);//加入队尾

vis[nx][ny]=1;

dist[nx][ny]=dist[x][y]+1;

}

}

}

}

先bfs预处理能到达的点,不能到达终点则输出-1,否则dp。dp[i]-到达i点后要到达终点需要的步数的期望。对每一个能到达的点x0,假设其相邻的能到达的点有x1、x2、x3.则dp[x0]=1+dp[x1]/3+dp[x2]/3+dp[x3]。

3.二分查找和三分对比。

首先是二分查找法,时间复杂度O(2log2(n)):
static bool Find(int[] sortedArray, int number)
{
 if (sortedArray.Length == 0)
  return false;
 int start = 0;
 int end = sortedArray.Length - 1;       
 while (end >= start)
 {        
  int middle = (start + end) / 2;       
  if (sortedArray[middle] < number)       
   start = middle + 1;       
        else if (sortedArray[middle] > number)         
   end = middle - 1;        
  else
   return true;       
 }     
 return false;
}

 

然后是三分查找算法,时间复杂度O(3log3(n)):
static bool Find(int[] sortedArray, int number)
{
 if (sortedArray.Length == 0)
  return false;
 int start = 0;
 int end = sortedArray.Length - 1;
 while (end >= start)
 {
  int firstMiddle = (end - start) / 3 + start;
  int secondMiddle = end - (end - start) / 3;
  if (sortedArray[firstMiddle] > number)
   end = firstMiddle - 1;
  else if (sortedArray[secondMiddle] < number)
   start = secondMiddle + 1;
  else if (sortedArray[firstMiddle] != number && sortedArray[secondMiddle] != number)
  {
   end = secondMiddle - 1;
   start = firstMiddle + 1;
  }
  else
   return true;
 }
 return false;
}

对比可以发现,三分查找算法的时间复杂度要比二分查找算法的时间复杂度低,
但是实际上效率并没有二分查找算法高,因此我们不能过于迷信一个算法的时间
复杂度。

总结:这一部分真心比较懵,就不多说了,还要好好在做些题。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章