原题链接:蓝桥杯2018年第九届真题-调手表
题目大意:
这个题目有点绕,我帮大家捋一捋题意,就是说小明现在手表上有两个按键,一个按下去时间+1,一个按下去时间+k,然后题目问的是在一个0–n-1的时间差里,调到这里面任意一个时间所需要的最小步数的最大值。
例如:样例当总时间为n=5,按键k=3:
调到0所需要的最小步数:0 不用动
调到1所需要的最小步数:1 按+1键
调到2所需要的最小步数:2 先按+1键 再按+1键
调到3所需要的最小步数:1 按+3键
调到4所需要的最小步数:2 按+3键 再按+1键
因此答案为这里面所有最小步数的最大值,即2,即任何一个时间点最多只需要按两次就能调过来。
解题思路:
BFS的思想,用一个队列先存储第一个走到的时间状态,即时间0,步数为0,然后根据队首元素往后搜可能到达的两个时间点(即+1之后的时间和+k之后的时间),如果这两个时间没有走过那就存进队列,对应时间状态的步数+1,最后找到这些步数里的最大值就行。
参考代码:
#include <bits/stdc++.h>
using namespace std;
int ans=0,n,k,t,book[100001];
typedef struct
{ int num;//当前状态里的时间
int step; //走到这个状态所需要的步数
}Status;//定义状态结构体
queue<Status> q;
int main()
{
cin>>n>>k;
Status start,f,now1;//起始 首元素 当前状态
start.step=0;
start.num=0;
book[0]=1;
q.push(start);//先插入当前状态
while(!q.empty())
{
f=q.front();//取出首元素
q.pop();
t=(f.num+1)%n;//按+1键后的时间
if(!book[t])//如果这个时间没有走过
{ book[t]=1;//标记走过
now1.num=t;
now1.step=f.step+1;
ans=max(ans,now1.step); //更新答案
q.push(now1);//把当前状态插入
}
t=(f.num+k)%n;//按+k键后的时间
if(!book[t])//如果这个时间没有走过
{ book[t]=1;//标记走过
now1.num=t;
now1.step=f.step+1;
ans=max(ans,now1.step);
q.push(now1);//把当前状态插入
}
}
cout<<ans;
return 0;
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复