链接:https://ac.nowcoder.com/acm/contest/331/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
小希现在要从寝室赶到机房,路途可以按距离分为N段,第i个和i+1个是直接相连的,只需要一秒钟就可以相互到达。
炫酷的是,从第i个到第i+2^p个也是直接相连的(其中p为任意非负整数),只需要一秒钟就可以相互到达。
更炫酷的是,有K个传送法阵使得某些u,v之间也是直接相连的,只需要一秒钟就可以相互到达,当然,由于设备故障,可能会有一些u=v的情况发生。
现在小希为了赶路,她需要在最短的时间里从寝室(编号为1)到达机房(编号为N),她不希望到达这N个部分以外的地方(不能到达位置N+1),也不能走到比自己当前位置编号小的地方(比如从5走到3是非法的)。
她想知道最短的时间是多少。
输入描述:
第一行输入两个整数N,K,表示路途的段数和传送法阵的数量。
从第二行开始K行,每行两个整数ai,bi表示两个位置之间相连。
2≤N≤1,000,000,000
0≤K≤15
输出描述:
输出一个整数,表示从寝室到机房最短的时间是多少秒。
示例1
输入
12 2
1 5
6 6
输出
3
示例2
输入
17 2
2 5
8 9
输出
1
3种走法:我定义为:1.一次一次走法 2. 2^p走法 3. 传送走法
题意:不解释~
题解:贪心想一下,每次走2^p次肯定比一次一次走法快,然后就用2^p走法 与 传送加2^p走法进行比较,就可以啦,而且这种走法还可以贪心,就是一次走一步最大的,然后走小的~~~至于为啥可以~我就说:贪心贪心~~上代码:
#include <iostream>
using namespace std;
typedef long long ll;
const int MAX = 31;
ll a[MAX];
void init(){
a[0]=1;
for (int i = 1; i <= 30;i++){//二的多少次方,1e9就到30了
a[i]=a[i-1]*2;
}
}
ll zhao(ll u,ll v){
ll sum=0;
while(u<v){
for (int i = 30; i >= 0;i--){//贪心,从大步到小步
if(u+a[i]<=v){
u+=a[i];
sum++;
break;
}
}
}
return sum;
}
int main(){
init();
ll n,k;
cin >> n >> k;
ll ans;
ans=zhao(1,n);//纯2^p走法
for (int i = 0; i < k;i++){
int u,v;
cin >> u >> v;
if(u>v) swap(u,v);
if(u==v) continue;
ans=min(ans,zhao(1,u)+1+zhao(v,n));//传送走法+2^p走法,与 纯2^p走法求最小值
}
cout << ans << endl;
return 0;
}