命运石之门
Time Limit: 1000 MS Memory Limit: 256 MB
Submit Status
“这一切都是命运石之门的选择!“
凶真博士发明了能够逆转时间的电话微波炉,也就是微型时光机。每次时光机开机时,时光机顶部的数字屏上会随机显示一个数字n,表示此时在什么也不放置的情况下启动微波炉,会回到距离现在n小时之前。凶真博士可以通过烤香蕉的形式改变数字n。如果凶真博士一次烤两根香蕉,数字n会变为原来的两倍。如果凶真博士一次烤三根香蕉,数字n会减去3。如果凶真博士一次烤一根香蕉或三根以上香蕉,时光机就会爆炸。此外,如果在烤香蕉的过程中,n太大(n>500000)或n太小(n≤0),时光机也会因为太阳黑子带来的压力过大而爆炸。
凶真博士想要回到距离现在m小时之前的世界,他至少要花费多少根香蕉呢?
Input
两个空格隔开的整数n,m.
1≤n,m≤500000
Output
一个整数,表示最少需要烤多少个香蕉。
如果怎样烤香蕉都不能回到m小时之前的世界,输出-1.
Sample input and output
|
|
|
|
Hint
样例1:可以先烤两根香蕉将n从4变为8,再烤三根香蕉将其变为5.
Source
2018 UESTC ACM Training for Graph Theory
题解:
bfs中,每次有两种走向,一个是当前值*2,一个是当前值-3,用dis记录消耗香蕉数,总体实现出来就和spfa的思想一样
AC代码为:
#include<bits/stdc++.h>
using namespace std;
long long dis[1000010], n, m, i;
long long bfs(void)
{
queue<long long> que;
long long v;
v = 0;
que.push(n);
dis[n] = 0;
while (!que.empty())
{
long long x = que.front();
que.pop();
for (long long i = 1; i <= 2; i++)
{
long long nx;
if (i == 1) nx = x * 2;
if (i == 2) nx = x - 3;
if (i == 1 && nx>0 && nx <= 500000 && dis[x] + 2<dis[nx])
{
que.push(nx);
dis[nx] = dis[x] + 2;
if (nx == m) { v = 1; break; }
}
else if (i == 2 && nx>0 && nx <= 500000 && dis[x] + 3<dis[nx])
{
que.push(nx);
dis[nx] = dis[x] + 3;
if (nx == m) { v = 1; break; }
}
}
if (v == 1) break;
}
if (v == 1) return dis[m];
else return -1;
}
int main()
{
scanf("%lld%lld", &n, &m);
if (n == m) { printf("0\n"); return(0); }
for (long long i = 0; i <= 600000; i++)
dis[i] = 10000000000000000;
printf("%lld\n", bfs());
return(0);
}