• kuangbin专题总结一 简单搜索


    A - 棋盘问题:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

    解题思路:DFS,在这里有两个搜索方向,同时对每个位置的描述由xy坐标完成,第一次我尝试使用pair+vector保存棋盘位置,用两个数组描述放过棋子的行和列但是由于清除标记没做好WA了。这里是因为DFS搜索中状态转移没确定好,导致清楚标记复杂而出错,改为逐行递归逐列遍历。在这里要注意用getchar()清除读取时回车,还有一次WA是因为把边界检查放在了结果检查的后边(因为检测num修改cnt实在DFS(i+1)中,先进行边界检查就导致解 的结果变少)。

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int MAXN = 10;
    char g[MAXN][MAXN];
    int place[MAXN],n,k,cnt,num;
    void DFS(int i)//按行递归,逐列遍历
    {
        if(num==k)
        {
            cnt++;
            return ;
        }
        if(i>=n)
            return ;
        for(int j=0;j<n;j++)
        {
            if(!place[j]&&g[i][j]=='#')
            {
                place[j] = 1;
                num++;
                DFS(i+1);
                place[j] = 0;//清除标记
                num--;
            }
        }
        DFS(i+1);//i行也可以不放棋子
    }
    int main()
    {
        while(scanf("%d%d",&n,&k))
        {
            if(n==-1&&k==-1)
                break;
            char c;
            getchar();
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                    scanf("%c",&g[i][j]);
                getchar();
            }
            cnt = 0;
            num = 0;
            memset(place,0,sizeof(place));
            DFS(0);
            cout<<cnt<<endl;
        }
    }

    B - Dungeon Master

    You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides. 

    Is an escape possible? If yes, how long will it take? 

    这是一个三维BFS搜索,确定方向设置三维数组解决。注意DFS和BFS的使用场合,DFS适合求出路径和具体信息,BFD适合求出最短路径和长度,这里显然用BFS比较好。。

    #include <iostream>
    #include<vector> 
    #include<queue>
    #include<string>
    #define MAX 31
    using namespace std;
    int dir[6][3] = { {1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1} };
    struct node{
        int l;
        int r;
        int c;
        int step;
    };
    int dfs(node start,node to);
    void Read(int l,int r,int c);
    
    char g[MAX][MAX][MAX];
    node start,to;
    int l,r,c,d=0;
    bool judge(int tl,int tr,int tc)
    {
        if(tl<0||tr<0||tc<0||tl>=l||tr>=r||tc>=c||g[tl][tr][tc]=='#')
            return false;
        return true;
    }
    int main()
    {
        cin>>l>>r>>c;
        while(l!=0&&r!=0&&c!=0)
        {
            Read(l,r,c);
            d = dfs(start,to);
            if(d != -1)
                printf("Escaped in %d minute(s).
    ", d);
            else
                printf("Trapped!
    ");
            cin>>l>>r>>c;
        }
    }
    void Read(int l,int r,int c)
    {
        int k,i,j;
        string str;
        for(k=0;k<l;k++)
        {
            for(i=0;i<r;i++)
            {
                cin>>str;
                for(j=0;j<c;j++)
                {
                    if(str[j]=='S')
                    {
                        start.r =i;
                        start.c = j;
                        start.l = k;
                    }
                    if(str[j]=='E')
                    {
                        to.r = i;
                        to.c = j;
                        to.l = k;
                    }
                    g[k][i][j] = str[j];
                }
            }
            getchar();
        }
    }
    int dfs(node start,node to)
    {
        int distance = 0;
        queue<node> Q;
        Q.push(start);
        while(!Q.empty())
        {
            start = Q.front();
            Q.pop();
            if(start.c==to.c&&start.r==to.r&&start.l==to.l)
                return start.step;
            for(int i=0; i<6; i++)
            {
                node q = start;
                q.r += dir[i][0];
                q.c += dir[i][1];
                q.l += dir[i][2];
                q.step += 1;
    
                if(judge(q.l,q.r,q.c))
                {
                    g[q.l][q.r][q.c] = '#';
                    Q.push(q);
                }
            }
        }
        return -1;
    }

    C - Catch That Cow

    armer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

    * Walking: FJ can move from any point X to the points - 1 or + 1 in a single minute
    * Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

    If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

    这个题目WA了好多次,,首先确定用数组保存到达每个点的最短距离和到达的步数,然后BFS分别在三种情况下搜索,已经搜索过了就不用再次搜素(step肯定比之前大,就不是最优解了),这里主要是没有注意到用数组保存状态还有边界检查,导致超时。

    #include <stdio.h>  
    #include <string.h>  
    #include <queue>  
    using namespace std;  
    const int N = 1000000;  
    int map[N+10];  
    int n,k;  
    struct node  
    {  
        int x,step;  
    };   
    int check(int x)  
    {  
        if(x<0 || x>=N || map[x])  
            return 0;  
        return 1;  
    }  
    int bfs(int x)  
    {  
        int i;  
        queue<node> Q;  
        node a,next;  
        a.x = x;  
        a.step = 0;  
        map[x] = 1;  
        Q.push(a);  
        while(!Q.empty())  
        {  
            a = Q.front();  
            Q.pop();  
            if(a.x == k)  
                return a.step;  
            next = a;  
            //每次都将三种状况加入队列之中  
            next.x = a.x+1;  
            if(check(next.x))  
            {  
                next.step = a.step+1;  
                map[next.x] = 1;  
                Q.push(next);  
            }  
            next.x = a.x-1;  
            if(check(next.x))  
            {  
                next.step = a.step+1;  
                map[next.x] = 1;  
                Q.push(next);  
            }  
            next.x = a.x*2;  
            if(check(next.x))  
            {  
                next.step = a.step+1;  
                map[next.x] = 1;  
                Q.push(next);  
            }  
        }  
        return -1;  
    }  
      
    int main()  
    {  
        int ans;  
        while(~scanf("%d%d",&n,&k))  
        {  
            memset(map,0,sizeof(map));  
            ans = bfs(n);  
            printf("%d
    ",ans);  
        }  
        return 0;  
    }  
    E - Find The Multiple 

    Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.

    BFS搜素,两个状态是ans = ans*10+1,ans*=10,注意边界检查

    #include <stdio.h>
    int n,flat;
    unsigned long long b;
    void DFS(unsigned long long a,int step)
    {
        if(flat||step==19)
        {
            return ;
        }
        if(a%n==0)
        {
            printf("%I64u
    ",a);
            flat=1;
            return ;
        }
        else
        {
            DFS(a*10,step+1);
            DFS(a*10+1,step+1);
        }
        return ;
    }
    int main()
    {
        while(scanf("%d",&n),n)
        {
            flat=0;
            DFS(1,0);
        }
        return 0;
    }
  • 相关阅读:
    DevOps、CI、CD都是什么鬼?
    卧槽!华为《Linux中文手册》火了,完整版 PDF 开放下载!
    MongoDB 常用运维实践总结
    谈谈变更过程中的运维意识
    Ping原理详解
    为什么Redis要比Memcached更火?
    一篇文章教你搞懂日志采集利器 Filebeat
    工程师姓什么很重要!别再叫我“X工”!!!
    这些 Shell 分析服务器日志命令集锦,收藏好
    Linux下找出吃内存的方法总结
  • 原文地址:https://www.cnblogs.com/joeylee97/p/6128310.html
Copyright © 2020-2023  润新知