zoukankan      html  css  js  c++  java
  • 搜索入门

    A - Lake Counting POJ - 2386

    题意:W是水洼,连起来的W算同一个水洼(是九宫格内的连起来)

    解题思路:dfs搜索,搜索不到了就继续,每一个dfs都可以搜到一个水坑,简而言之,总的dfs的次数就是水坑的个数(dfs重新调用的dfs不算)
     
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<sstream>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    #define PI 3.14159265358979323846264338327950
    
    int N,M;
    const int MAX_N=103;
    char field[MAX_N][MAX_N];
    
    void dfs(int x,int y)
    {
        field[x][y]='.';
        for(int dx=-1;dx<=1;dx++)
        {
            for(int dy=-1;dy<=1;dy++)
            {
                int nx=x+dx,ny=y+dy;
                if(0<=nx && nx<N && 0<=ny && ny<M && field[nx][ny]=='W')
                    dfs(nx,ny);
            }
        }
        return ;
    }
    
    void solve()
    {
        int res =0;
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<M;j++)
            {
                if(field[i][j]=='W')
                {
                    dfs(i,j);
                    res++;
                }
            }
        }
        printf("%d
    ",res);
    }
    
    int main()
    {
        cin>>N>>M;
        for(int i=0;i<N;i++)
            for(int j=0;j<M;j++)
                cin>>field[i][j];
        solve();
        
    }
    View Code

    B - N皇后问题 HDU - 2553 

     在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 
    你的任务是,对于给定的N,求出有多少种合法的放置方法。 

    Input共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。Output共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。Sample Input

    1
    8
    5
    0

    Sample Output

    1
    92
    10


    解题思路:可以说是入门的dfs了,直接用数组的i来储存行就不用考虑行的重复了, 只需要进行对列和对角线的判断就好了,先打个表,不然可能会超时哦

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<sstream>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    #define PI 3.14159265358979323846264338327950
    
    int map[12],a[12],n,sum;
    
    int check(int x)
    {
        for(int i=0;i<x;i++)
        {
            if(map[i]==map[x]||abs(map[i]-map[x])==abs(i-x))
                return 0;
        }
                return 1;
    }
    void dfs(int x)
    {
        if(x==n)
            sum++;
        else
        {
            for(int j=1;j<=n;j++)
            {
                map[x]=j;
                if(check(x))
                    dfs(x+1);
            }
        }
    }
    
    int main()
    {
        for(int i=1;i<11;i++)
        {
            sum=0;
            n=i;
            dfs(0);
            a[i]=sum;
        }
        int n;
        while(scanf("%d",&n) && n)
        {
            printf("%d
    ",a[n]);
        }
    }
    View Code

    C - Catch That Cow POJ - 3278 

    题目大意:人追牛,人可以加减一步或者两倍

    解题思路:就是bfs搜索,注意数组的大小要开两倍
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<sstream>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    #define PI 3.14159265358979323846264338327950
    
    struct point
    {
        int x,y,step;
    }st;
    
    queue<point>q;
    int vis[200002];
    int n,m,flat;
    
    int bfs()
    {
        while(!q.empty())
        {
            q.pop();
        }
        
        memset(vis,0,sizeof(vis));
        vis[st.x]=1;
        q.push(st);
        while(!q.empty())
        {
            point now=q.front();
            if(now.x==m)
                return now.step;
            q.pop();
            for(int j=0;j<3;j++)
            {
                point next = now;
                if(j == 0)
                    next.x=next.x+1;
                else if(j==1)
                    next.x=next.x-1;
                else
                    next.x=next.x*2;
                ++next.step;
                if(next.x==m)
                    return next.step;
                if(next.x>=0 && next.x<=200000 && !vis[next.x])
                {
                    vis[next.x]=1;
                    q.push(next);
                }
            }
        }
        return 0;
    }
    int main()
    {
        while (~scanf("%d %d", &n, &m))
        {
            st.x = n;
            st.step=0;
            printf("%d
    ", bfs());
        }
      return 0;
            
    }
    View Code

    D - Dungeon Master POJ - 2251 

    题意:给你一个多维的迷宫,问能不能可以从起点走到终点,可以上下穿梭层数,也可以东南西北走,都是一秒一个单位,可以到终点就输出步数,不可以就输出那句话

    解题思路:其实和普通的二维迷宫差不多,就是多了一个层数,也就是多了两个方向(上下层数)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define ll long long
    int const maxn = 35;
    const int mod = 1e9 + 7;
    int gcd(int a, int b) {
        if (b == 0) return a;  return gcd(b, a % b);
    }
    
    char map[maxn][maxn][maxn];
    int vis[maxn][maxn][maxn];
    int k,n,m,sx,sy,sz,ex,ey,ez;
    int dir[6][3]={{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
    
    struct node
    {
        int x,y,z,step;
    };
    int check (int x,int y,int z)
    {
        if(x<0 || y<0 || z<0 || x>=k || y>=n || z>=m)
            return 1;
        else if(map[x][y][z]=='#')
            return 1;
        else if(vis[x][y][z])
            return 1;
        return 0;
    }
    
    int bfs()
    {
        node a,next;
        queue<node>que;
        a.x=sx;  a.y=sy;  a.z=sz;
        a.step=0;
        vis[sx][sy][sz]=1;
        que.push(a);
        while(!que.empty())
        {
            a=que.front();
            que.pop();
            if(a.x == ex && a.y == ey && a.z == ez)
                return a.step;
            for(int i=0;i<6;i++)
            {
                next=a;
                next.x=a.x+dir[i][0];
                next.y=a.y+dir[i][1];
                next.z=a.z+dir[i][2];
                if(check(next.x,next.y,next.z))
                    continue;
                vis[next.x][next.y][next.z]=1;
                next.step=a.step+1;
                que.push(next);
    
            }
        }
        return 0;
    
    }
    
    
    int main()
    {
        while(~scanf("%d %d %d",&k,&n,&m))
        {
            if(k==0 && n==0 && m==0)
                break;
            for(int i=0;i<k;i++)
            {
                for(int j=0;j<n;j++)
                {
                    scanf("%s",map[i][j]);
                    for(int r=0;r<m;r++)
                    {
                        if(map[i][j][r]=='S')
                        {
                            sx=i;sy=j;sz=r;
                        }
                        else if(map[i][j][r]=='E')
                        {
                            ex=i;ey=j;ez=r;
                        }
                    }
                }
            }
            memset(vis,0,sizeof(vis));
            int ans;
            ans=bfs();
            if(ans)
                printf("Escaped in %d minute(s).
    ",ans);
            else
                printf("Trapped!
    ");
        }
        return 0;
    }
    View Code

    E - Prime Path HDU - 1973

    题意:给你两个四位数,都是素数,每次改变可以改变其中的任何一个数字,但要求改变后的四位数(没有前导零)依然是素数,问最少改变几次可以使得第一个数改为第二个数

    思路:可以先用埃氏筛法把1000-9999的所有的素数都选出来,之后就四个位数,每个位数最多改变八次,就搜索一下,我开了isprime和step两个数组,当然也可以开一个结构体,但只改变一个数字需要花点功夫,我是枚举了个位,十位,百位,千位。
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define ll long long
    int const maxn = 9999;
    const int mod = 1e9 + 7;
    int gcd(int a, int b) {
        if (b == 0) return a;  return gcd(b, a % b);
    }
    
    bool isprime[maxn];
    int step[maxn];
    bool vis[maxn];
    int num1,num2;
    void getprime(int n)
    {
        for(int i=0;i<=n;i++)
            isprime[i]=true;
        isprime[0]=isprime[1]=false;
        for(int i=2;i<=n;i++)
        {
            for(int j=2*i;j<=n;j=j+i)
                isprime[j]=false;
        }
    }
    
    int bfs(int st )
    {
     
        vis[st]=true;
        step[st]=0;
        queue<int>que;
        que.push(st);
        while(que.size())
        {
            int p=que.front();
            que.pop();
            if(p == num2)
            {
                return step[num2];
                break;
            }
            int ge=p % 10;
            int shi=(p/10)%10;
            int bai=(p/100)%10;
            int qian=p/1000;
            for(int i=0;i<=9;i++)
            {
                int next;
                if(i!=ge)
                {
                    next=p-ge+i;
                    if(next>=1000 && next<=9999 && isprime[next] && vis[next]==false)
                    {
                        step[next]=step[p]+1;
                        que.push(next);
                        vis[next]=true;
                        //   cout<<"ge";
                    }
                }
                if(i!=shi)
                {
                    next=p-shi*10+i*10;
                    if(next>=1000 && next<=9999 && isprime[next] && vis[next]==false)
                    {
                        step[next]=step[p]+1;
                        que.push(next);
                        vis[next]=true;
                    //    cout<<"shi";
                    }
                }
                if(i!=bai)
                {
                    next=p-bai*100+i*100;
                    if(next>=1000 && next<=9999 && isprime[next] && vis[next]==false)
                    {
                        step[next]=step[p]+1;
                        que.push(next);
                        vis[next]=true;
                    //    cout<<"bai";
                    }
                }
                if(i!=qian)
                {
                    next=p-qian*1000+i*1000;
                    if(next>=1000 && next<=9999 && isprime[next] && vis[next]==false)
                    {
                        step[next]=step[p]+1;
                        que.push(next);
                        vis[next]=true;
                   //     cout<<"qian";
                    }
                }
            }
                
        }
        return -1;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        getprime(9999);
        while(t--)
        {
            memset(vis,false,sizeof(vis));
            memset(step,0,sizeof(step));
            scanf("%d %d",&num1,&num2);
            
    //        for(int i=2;i<=9999;i++)
    //            if(isprime[i])
    //                cout<<i<<" ";
            int ans=bfs(num1);
            if(ans>=0)
              printf("%d
    ",ans);
            else
                printf("Impossible
    ");
        }
    }
    View Code
  • 相关阅读:
    redis 5.0.5集群部署
    python 继承、多继承与方法重写(二)
    python 脚本监控硬件磁盘状态并发送报警邮件
    k8s 应用程序获取真实来源ip
    yolov5 安装尝试
    安装pygrib
    ubuntu编译ecodes
    python mpi实验
    mint install gaussian 16
    flask 使用工程外的static文件位置
  • 原文地址:https://www.cnblogs.com/smallhester/p/10296264.html
Copyright © 2011-2022 走看看