zoukankan      html  css  js  c++  java
  • swpu寒假集训-简单搜索 部分题解

    B - Catch That Cow

    题目如下

    那么题意呢,很直观。给俩数n k,在横坐标中,n表示人的位置,k表示牛的位置。人有两类行动方式(行动一次花费一分钟),一种前进1或后退1,一种直接位置*2,而牛不会动,人刚好到牛的位置就结束,求最小时间。

    按部就班bfs写就完了。

    创建一个队列,一个数存位置,一个数存行动次数。

    单组输入n k,如果n>=k,证明人在牛之前,人只需要后退n-k个位置,也就是n-k分钟,就直接输出了。如果不是,那就添加到队列去处理。

    如果队列中有数据,就取出来。判断是否等于k,满足则代表人到牛的位置了,输出行动次数。不满足则开始行动。

    在行动中,会发现一个问题,比如从5到10,可以用第一类行动,前进5次,花费5分钟,也可以用第二类,花费1分钟。那么怎么选择最短的呢?

    那么就需要开一个bool型的数组来记录是否已经到过这个位置了。如果在进行行动时,发现下一步到的位置是已经记录了到过的,就停止这步行动那么,如果判断没有到过这个位置,就可以建立分支。从起始点,可以有三个分支,而第二步行动时每个分支又有三个分支,依次形成一个“树”。按照题意0 ≤ n,k≤ 100,000,也就是建分支直到位置到100000(当然实际上,当人到牛的位置时就停止不建了)

    别忘了:1.到过一个位置后标记已经到过了。2.当你在下一步行动之前,把队列中上一步的位置信息删除掉,否则就一直循环下去了。

    那么最后的代码奉上

    #include<iostream>
    #include<queue>
    using namespace std;
    int n,k;
    bool visit[100005];
    struct node {
        int x;
        int ans;
    };
    int bfs() {
        queue<node> q;
        q.push({n,0});
        while(q.size()) {
            node now=q.front();
            if(now.x==k)
                return now.ans;
            else if(!visit[now.x]) {
                visit[now.x]=1;
                if(now.x+1<=100000)
                    q.push({now.x+1,now.ans+1});
                if(now.x-1>=0)
                    q.push({now.x-1,now.ans+1});
                if(now.x*2<=100000)
                    q.push({now.x*2,now.ans+1});
            }
            q.pop();
        }
        return 0;
    }
    int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>k;
        if(n>=k)
            cout<<n-k<<endl;
        else
            cout<<bfs()<<endl;
        return 0;
    }
    View Code

    C - Find The Multiple

    题目如下

    这道题也比较一般,根据题意。多组数,求每个数的只含有0 1的最小公倍数。

    输入的数>>需输出的数>>输出的数拆解后

    1>>1>>1

    2>>10>> 1*10

    3>>111>> (1*10+1)*10+1

    4>>100>> 1*10*10

    5>>10>> 1*10

    6>>1110>> ((1*10+1)*10+1)

     ······

    可以看出,其实这是有规律的,那么可以从x=1开始,判断x*10%n或(x*10+1)%n是否为0,然后同样的,如果这步操作没有满足条件的,这两个分支再来开分支。

    需要注意的是:1.数据大。2.每步操作完了删除队列中的这个数据,理由同上题。

    完整代码

    #include<iostream>
    #include<queue>
    using namespace std;
    int n;
    queue <long long int> q;
    long long int bfs()
    {
        while(q.size())
        {
            q.pop();
        }
        q.push(1);
        while(q.size())
        {
            if(q.front()%n==0)
            {
                return q.front();
            }
            long long int temp=q.front();
            q.pop();
            q.push(temp*10);
            q.push(temp*10+1);
        }
        return 0;
    }
    
    int main()
    {
        while(cin>>n&&n)
        {
            cout<<bfs()<<endl;
        }
        return 0;
    }
    View Code

    E - Oil Deposits

    题目↓↓↓↓↓↓↓↓↓↓

    这道题是多组数据。每组第一行给两个数,分别代表行数和列数,接下来有一个图,“*”为土,“@”为油田。规定一块油田可以上下左右斜着连在一起,找图里共有几块油田。

    bcehj

  • 相关阅读:
    绝对相等与弱相等
    css3之媒体查询
    css3新增选择器
    BFC渲染机制
    css优先级及其对应的权重
    滚动指示器
    web储存的初级运用
    setTimeout与setInterval的使用
    原生js获取left值和top值
    canvas圆形进度条
  • 原文地址:https://www.cnblogs.com/bigcn/p/12229668.html
Copyright © 2011-2022 走看看