swpu寒假集训-简单搜索 部分题解

B - Catch That Cow

题目如下

swpu寒假集训-简单搜索 部分题解_第1张图片

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

按部就班bfs写就完了。

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

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

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

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

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

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

那么最后的代码奉上

#include
#include
using namespace std;
int n,k;
bool visit[100005];
struct node {
    int x;
    int ans;
};
int bfs() {
    queue 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<endl;
    else
        cout<endl;
    return 0;
}
View Code

 

C - Find The Multiple

题目如下

swpu寒假集训-简单搜索 部分题解_第3张图片

这道题也比较一般,根据题意。多组数,求每个数的只含有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
#include
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<endl;
    }
    return 0;
}
View Code

 

E - Oil Deposits

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

 

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

 

 

 

 

 

 

 

bcehj

你可能感兴趣的:(swpu寒假集训-简单搜索 部分题解)