代码源:147、BFS练习1

394 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情logo.png

题目描述

这是4月2日代码源div2的每日一题。

知识点:BFS

BFS练习1 - 题目 - Daimayuan Online Judge

给你一个数字a,每次可以选择下面四种操作中的一种:

  1. 把数字a加上一。
  2. 把数字a乘以2。
  3. 把数字a乘以3。
  4. 把数字a减去一。

问把这个a变成b最少需要多少步。

你要回答q个询问,b1,b2,…,bq,输出把a变成b1,b2,…,bq的最小步数。

输入格式

第一行两个整数a,q。

接下来一行q个整数b1,…,bq。

输入格式

输出q个数字,分别表示把a变成b1,b2…,bq的最小步数。

样例输入

3 10
1 2 3 4 5 6 7 8 9 10

样例输出

2 1 0 1 2 1 2 2 1 2

数据规模

对于所有数据,保证1≤a,q,bi≤10^5。

问题解析

这题也算是个很经典的bfs题了,这题的数字转化成一个树的样子就是这样:

                  a
              / |   | \
             /  |   |  \
           a*2 a*3  a-1  a+1

一个数可以向下衍生出4个不同的样子,它的四个分支又可以各自伸出4个分支。当在这个树上找到我们要转化的目标值时,第一次出现的层数就是它经过操作的次数。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 300050;
int a[N], f[N];

inline int read() {
    int x = 0; char ch = getchar();
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x;
}

void write(int x) {
    if (x > 9) write(x / 10);
    putchar(x % 10 | '0');
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, num;
    num = read(), n = read();
    vector<int>v(n);
    for (int i = 0; i < n; i++)
    {
        v[i] = read();
        a[v[i]] = -1;
    }
    queue<int>que;
    que.push(num);
    int res = 0;
    while (!que.empty()&&n)
    {
        int len = que.size();
        for (int i = 0; i < len; i++)
        {
            int ans = que.front();
            que.pop();
            if (a[ans] == -1)
            {
                a[ans] = res;
                n--;
            }
            if (ans * 3 < 100050 && f[ans * 3] == 0)
            {
                que.push(ans * 3);
                f[ans * 3] = 1;
            }
            if (ans * 2 < 100050 && f[ans * 2] == 0)
            {
                que.push(ans * 2);
                f[ans * 2] = 1;
            }
            if (ans - 1 > 0 && f[ans - 1] == 0)
            {
                que.push(ans - 1);
                f[ans - 1] = 1;
            }
            if (ans + 1 < 100050 && f[ans + 1] == 0)
            {
                que.push(ans + 1);
                f[ans + 1] = 1;
            }
        }
        res++;
    }
    for (auto i : v)
    {
        write(a[i]); 
        putchar(' ');
    }
    
    return 0;
}