bfs(广度优先搜索)

P1032 字串变换

这道题很多坑,坑了我一天
1.设置一个map,防止重复搜索
2.字符串的子串有多处相同,第五个点wa
3.自己代码写的有点乱
4.标志串不能简单直接替换,因为把y 换成yz就会死循环,要弄个别的字符来替换
5.replace的两种写法,迭代器法和下标法
总之:这题很烦

#include <bits/stdc++.h>
using namespace std;
string a[8],b[8];

struct node
{
    string x;
    int cnt;//cnt记录步数
};
queue<node>q;
map<string,int>ma;//防止重复搜索
int main()
{

    int n=0;
    int flag=0;
    while(cin>>a[n]>>b[n])
    {
        n++;if(n>6)break;
    }
    q.push({a[0],0});//先把起点入队,开始时cnt=0
    while(!q.empty())//开始搜索,用队列实现BFS,当队列为空还未到终点,则无法达到终点(求最短步数实际上已经保证了一定能到终点)
    {
        node tmp=q.front();q.pop();//按队列顺序依次取出队首tmp
        if(tmp.cnt>10)break;
        if(tmp.x==b[0]){printf("%d\n",tmp.cnt);flag=1;break;}//找到终点,输出答案,搜索结束
        //a[tmp.x][tmp.y]='1';//原节点变为"墙"
        if(ma[tmp.x])continue;
        else ma[tmp.x]=1;
        for(int i=1;i<n;i++)//四个方向搜索,寻找可行的下一个新节点
        {
            //newx=tmp.x+dir[i][0];
            //newy=tmp.y+dir[i][1];
            //if(newx>=1&&newx<=n&&newy>=1&&newy<=n&&a[newx][newy]=='0')
            //{a[newx][newy]='1';q.push({newx,newy,tmp.cnt+1});}//新节点入队,并且走到新节点的步数是原节点的步数加一
            string str1=tmp.x;
            while(1)
            {


                int t=str1.find(a[i]);
                if(t==-1)break;
                string str=tmp.x;
                str.replace(t,a[i].length(),b[i]);
                q.push({str,tmp.cnt+1});
                str1[t]='&';
                
            }
        }
    }
    if(flag==0)cout<<"NO ANSWER!"<<endl;
    return 0;
}

nefu1519 林大超市买水果-搜索

经典搜索题型,运用到回溯
一直纳闷这题 咋标记
理解:往两种方向发展
1.不选这个
2.选这个

#include <bits/stdc++.h>
using namespace std;
int n,m,sum,newx,newy,k,fl;//必须都要定义在前面,养成习惯
int a[35];
int flag[35];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
void dfs(int sum,int cnt)
{
    if(sum<0||cnt>k||fl==1)return ;
    if(sum==0&&cnt==k){fl=1;return ;}
    if(sum==0&&cnt!=k)return;
    for(int i=1;i<=n;i++)
    {
        if(flag[i])continue;
        flag[i]=1;
        dfs(sum-a[i],cnt+1);
        flag[i]=0;//回溯
    }
}
int main()
{
    cin>>m>>n>>k;
    int ant=0;
    for(int i=1;i<=n;i++){scanf("%d",&a[i]);ant+=a[i];}
    if(ant<m)printf("No\n");//特解直接处理
    else
    {
       dfs(m,0);
       if(fl)cout<<"Yes"<<endl;
       else cout<<"No"<<endl;
    }
    
    return 0;
}

nefu170201迷宫-搜索

记忆化搜索,把搜索结果存储起来,达到优化时间利用的结果

#include <bits/stdc++.h>
using namespace std;
char a[1001][1001];
int vis[1005][1005],flag[1005][1005];
int num[1000005];
int n,beginx,beginy,endx,endy,newx,newy,m;
int dir[8][2]={{1,0},{-1,0},{0,-1},{0,1}};//定义上下左右四个方向
struct node
{
    int x,y,cnt;//cnt记录步数
};
queue<node>q;
int main()
{

    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i]+1;//以1、1为起点输入二维字符数组
    int ant=0;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){

    if(flag[i][j]==0)
    q.push({i,j,0});//先把起点入队,开始时cnt=0
    int cnt=1;
    while(!q.empty())//开始搜索,用队列实现BFS,当队列为空还未到终点,则无法达到终点(求最短步数实际上已经保证了一定能到终点)
    {
        node tmp=q.front();q.pop();//按队列顺序依次取出队首tmp
       //找到终点,输出答案,搜索结束
        flag[tmp.x][tmp.y]=1;//原节点变为"墙"
        vis[tmp.x][tmp.y]=ant;
        num[ant]=max(num[ant],cnt);
        for(int i=0;i<4;i++)//四个方向搜索,寻找可行的下一个新节点
        {
            newx=tmp.x+dir[i][0];
            newy=tmp.y+dir[i][1];
            if(newx>=1&&newx<=n&&newy>=1&&newy<=n&&a[newx][newy]!=a[tmp.x][tmp.y]&&flag[newx][newy]==0)
            {flag[newx][newy]=1;cnt++;q.push({newx,newy,tmp.cnt+1});vis[newx][newy]=ant;num[ant]=max(num[ant],cnt);}//新节点入队,并且走到新节点的步数是原节点的步数加一
        }
    }
    ant++;
    }
    int x,y;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",num[vis[x][y]]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhoucheng_123/article/details/105232199