搜索题解

Posted j-j-j

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索题解相关的知识,希望对你有一定的参考价值。

1.Oil Deposits

  bfs,遍历每个满足条件的点,找到附近满足条件的点,再从这个点周围继续找点。

https://vjudge.net/problem/HDU-1241

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define N 105
char map[N][N];
bool vis[N][N];//标记的点
struct node
{ int x,y;
};
queue<node> q;
int fx[8]={1,0,-1,0,-1,1,-1,1},fy[8]={0,1,0,-1,1,-1,-1,1};
void bfs(int x,int y)
{ q.push({x,y});
 int nx,ny,i;
 while(q.size())
 { node now = q.front();
  q.pop();
  for(i=0;i<8;i++)//往满足条件的点周围的八个方向找点,满足条件就放入队列。
  { nx=now.x+fx[i];
   ny=now.y+fy[i];
   if(!vis[nx][ny]&&map[nx][ny]==@&&nx>=0&&nx<100&&ny>=0&&ny<100)
   { q.push({nx,ny});
    vis[nx][ny]=1;
   }
  }
 }
}
int main()
{ int m,n,i,j,sum;
 while(~scanf("%d %d",&n,&m))
 { if(n==0&&m==0)
   break;
   else
  { sum=0;
    getchar(); 
    memset(map,0,sizeof map);
    memset(vis,0,sizeof vis);
    for(i=0;i<n;i++)
  { for(j=0;j<m;j++)
   scanf("%c",&map[i][j]);
   getchar();
  }
  for(i=0;i<n;i++)
  { for(j=0;j<m;j++)
   { if(map[i][j]==@&&vis[i][j]==0)//从满足条件的点开始搜索,找到这个点周围的点并标记。
    { bfs(i,j);
      sum++;
    }
   }
  }
  printf("%d
",sum);
  }
 }
 return 0;
}

2.迷宫问题

https://vjudge.net/problem/OpenJ_Bailian-4127

用广度搜索,但是输出就不好搞,我们在创建队列结构体时,还要多创建一个变量用来记录这个点的根节点,这里我用了一个单独的函数输出,如果这个点不不是根节点,就递归并输出这个点,这样就能实现倒叙输出位置了。

#include<stdio.h>
#include<string.h>
#define n 5
using namespace std;
bool vis[n][n];//标记地图
int map[n][n]={0};
int fx[4]={0,1,0,-1};
int fy[4]={1,0,-1,0};
struct node
{ int x,y;
 int pre;
}q[100];
void print(int last)//递归输出这个点的上一个节点,直到根节点位置
{ if(q[last].pre!=last)
 print(q[last].pre);
 printf("(%d, %d)
",q[last].x,q[last].y);//递归后仍需输出这个点的坐标
}
int main()
{ int i=0,j=0,x,y;
 for(i=0;i<n;i++)
 for(j=0;j<n;j++)
 scanf("%d",&map[i][j]);
 vis[0][0]=1;
 int nx,ny,flag=0;
 q[0].x=0;
 q[0].y=0;
 q[0].pre=0;
 memset(vis,0,sizeof vis);
 int front=0,last=1;
 while(front<last)
 { 
  for(i=0;i<4;i++)
 { nx=q[front].x+fx[i];
  ny=q[front].y+fy[i];
  if(vis[nx][ny]==0&&map[nx][ny]==0&&nx>=0&&nx<5&&ny>=0&&ny<5)
  { vis[nx][ny]=1;
   q[last].x=nx;
   q[last].y=ny;
   q[last].pre=front;
   last++;
  }
  if(nx==4&&ny==4)
  { print(last-1);//我的last最后多加了一次,所以减了一
   break;
  }
 }
 front++;
 } 
 return 0;
}

3.红与黑

https://vjudge.net/problem/OpenJ_Bailian-2816

  用广域搜索,应为要找最多走好多块砖,所以我们对下一个点的限制就改为只要在图内就可以了。

 

#include<stdio.h>
#include<string.h>
#define N 25
int w,h,cnt;
char map[N][N];
bool vis[N][N];
int fx[4]={0,1,-1,0};
int fy[4]={1,0,0,-1};
void bfs(int x,int y)
{    int i,nx,ny;
    for(i=0;i<4;i++)
    {    nx=x+fx[i];
        ny=y+fy[i];
        if(map[nx][ny]==.&&!vis[nx][ny]&&nx>=0&&nx<h&&ny>=0&&ny<w)//无限走下去,把能走的黑砖都走了
        {    vis[nx][ny]=1;
            cnt++;
            bfs(nx,ny);
        }
    }
}
int main()
{    int i,j,x,y;
    while(~scanf("%d %d",&w,&h))
    {    memset(map,0,sizeof map);
        memset(vis,0,sizeof vis);
        if(w==0&&h==0)
        break;
        else
        {    cnt=1;
        for(i=0;i<h;i++)
        {    getchar();
            for(j=0;j<w;j++)
            {    scanf("%c",&map[i][j]);
                if(map[i][j]==@)
                {    x=i;
                    y=j;
                }
            }
        }
        bfs(x,y);
        printf("%d
",cnt);
        }
    }
    return 0;
}

 

4.Find a way

https://vjudge.net/problem/HDU-2612

  从两个人的出发点挨到遍历,找到每个人到目的点的最短时间,然后存到一个数组里面,最后把两个存时间的数组的值加起来,比较取最小值。

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define N 205
#define max 0x3f3f3f3f
char map[N][N];
int step1[N][N],step2[N][N];
bool vis[N][N];
struct node
{ int x,y;
};
queue<node>q;
int n,m,x1,x2,y1,y2;
int fx[4]={0,1,-1,0};
int fy[4]={1,0,0,-1};
void bfs(int x,int y,int step[][205])
{ int i;
 node now,next;
 vis[x][y]=1;
 step[x][y]=0;
 q.push({x,y});
 while(!q.empty())
 { now=q.front();
  q.pop();
  for(i=0;i<4;i++)
  { next.x=now.x+fx[i];
   next.y=now.y+fy[i];
   if(!vis[next.x][next.y]&&(map[next.x][next.y]==‘.‘||map[next.x][next.y]==‘@‘)&&next.x>=0&&next.x<n&&next.y>=0&&next.y<m)//注意下一个能走的点的条件是!‘#‘。
   { step[next.x][next.y]=step[now.x][now.y]+1;
    vis[next.x][next.y]=1;
    q.push(next);
   }
  }
 }
}
int main()
{ int i,j,maxx;
 while(scanf("%d %d",&n,&m)!=EOF)
 { maxx=max;
  memset(map,0,sizeof map);
  memset(step1,0,sizeof step1);
  memset(step2,0,sizeof step2);
  memset(vis,0,sizeof vis);
  for(i=0;i<n;i++)
  { scanf("%s",&map[i]);
   for(j=0;j<m;j++)
   { if(map[i][j]==‘Y‘)
    x1=i,y1=j;
    if(map[i][j]==‘M‘)
    x2=i,y2=j;
   }
  }
  bfs(x1,y1,step1);
  memset(vis,0,sizeof vis);
  bfs(x2,y2,step2);
  for(i=0;i<n;i++)
  { for(j=0;j<n;j++)
   { if(map[i][j]==‘@‘&&maxx>step1[i][j]+step2[i][j]&&step1[i][j]!=0&&step2[i][j]!=0)
    { maxx=step1[i][j]+step2[i][j];
    }
   }
  }
  printf("%d ",maxx*11);
 }
}

 

 

5.Catch That Cow

https://vjudge.net/problem/POJ-3278

这个题要注意就是农民的位置比牛前面时我们只有一步一步的倒退了,要分情况,牛在农夫前的情况:还是遍历每个点,但是跟之前的不一样,他不在单纯的加减了,他还要翻倍,我们在循环时对循环次数分情况来弄就可以了。

 

#include<stdio.h>
#include<string.h>
#include<queue>
#define N 100005
using namespace std;
bool vis[N];
int step[N];
int bfs(int n,int k)
{ int now,next,i;
 queue<int>q;
 q.push(n);
 vis[n]=1;
 while(!q.empty())
 { now=q.front();
  q.pop();
  for(i=0;i<3;i++)
  { if(i==0)
   next=now+1;
   else if(i==1)
   next=now-1;
   else if(i==2)
   next=now*2;
   if(next>=0&&next<=100000&&!vis[next])
   { step[next]=step[now]+1;
    vis[next]=1;
    q.push(next);
   }
   if(next==k)
   return step[next];
  }
 }
}
int main()
{ int n,k,i,sum=0;
 while(~scanf("%d %d",&n,&k))
 { if(n>=k)
 printf("%d
",n-k);
 else
 { memset(step,0,sizeof step);
  memset(vis,0,sizeof vis);
  sum=bfs(n,k);
  printf("%d
",sum);
 }
 }
 return 0;
}

以上是关于搜索题解的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode题解 - 树DFS部分简单题目代码+思路(70067165396554747346)

《安富莱嵌入式周报》第279期:强劲的代码片段搜索工具,卡内基梅隆大学安全可靠C编码标准,Nordic发布双频WiFi6 nRF7002芯片

#VSCode保存插件配置并使用 gist 管理代码片段

架构丰富的代码片段也应该用于产品列表吗?

Java 求解划分字母区间

LeetCode 240. 搜索二维矩阵 II c++/java详细题解