2018蓝桥杯比赛时间_第九届蓝桥杯[通俗易懂]

2018蓝桥杯比赛时间_第九届蓝桥杯[通俗易懂]标题:调手表小明买了块高端大气上档次的电子手表,他正准备调时间呢。在M78星云,时间的计量单位和地球上不同,M78星云的一个小时有n分钟。大家都知道,手表只有一个按钮可以把当前的数加一。在调分钟的时候,如果当前显示的数是0,那么按一下按钮就会变成1,再按一次变成2。如果当前的数是n-1,按一次后会变成0。作为强迫症患者,小明一定要把手表的时间调对。如果手表上…_楠楠买了块高端大气上档次的电子手表,他正准备调时间呢。在m78星云,时间的计量

2018蓝桥杯比赛时间_第九届蓝桥杯[通俗易懂]"

标题:调手表
小明买了块高端大气上档次的电子手表,他正准备调时间呢。
在 M78 星云,时间的计量单位和地球上不同,M78 星云的一个小时有 n 分钟。
大家都知道,手表只有一个按钮可以把当前的数加一。在调分钟的时候,如果当前显示的数是 0 ,那么按一下按钮就会变成 1,再按一次变成 2 。如果当前的数是 n – 1,按一次后会变成 0 。
作为强迫症患者,小明一定要把手表的时间调对。如果手表上的时间比当前时间多1,则要按 n – 1 次加一按钮才能调回正确时间。
小明想,如果手表可以再添加一个按钮,表示把当前的数加 k 该多好啊……
他想知道,如果有了这个 +k 按钮,按照最优策略按键,从任意一个分钟数调到另外任意一个分钟数最多要按多少次。
注意,按 +k 按钮时,如果加k后数字超过n-1,则会对n取模。
比如,n=10, k=6 的时候,假设当前时间是0,连按2次 +k 按钮,则调为2。
「输入格式」
一行两个整数 n, k ,意义如题。
「输出格式」
一行一个整数
表示:按照最优策略按键,从一个时间调到另一个时间最多要按多少次。
「样例输入」
5 3
「样例输出」
2
「样例解释」
如果时间正确则按0次。否则要按的次数和操作系列之间的关系如下:
1:+1
2:+1, +1
3:+3
4:+3, +1
「数据范围」
对于 30% 的数据 0 < k < n <= 5
对于 60% 的数据 0 < k < n <= 100
对于 100% 的数据 0 < k < n <= 100000
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。

dp显然可以,还是简单的完全背包,虽然像是价值确定,求最小质量,不过没关系,该怎么写还是怎么写;

我以为用数论也可以,毕竟就是公倍数公约数那点事;

公约数公倍数:学过数论了不起啊;

我:是啊,学过数论就是了不起啊。不过我没学过。

那种我也懒得写了,万一有时间再说吧,没时间就鸽了;

年轻人,要不要学bfs,效果也不错哦,一发AC的那种啊 (其实就类似数论的,不过只是完整模拟一遍,不用脑子的,还是把

数论鸽了吧);

DP 

1)类完全背包:(我这个dp[x]表示+x的最少操作数)

  #include"iostream"
  #include"cstring"
  #define INF 100000
  using namespace std;
  int a[5],N,K,dp[100001];
  int main(){
	  cin >> N >> K;
	  a[0] = 1;a[1] = K;
	  memset(dp,INF,sizeof(dp));
	  dp[0] = 0;
	  int Max = 0;
	  for(int j = 1;j <= N;j++)
	  for(int i = 0;i < 2;i++)
	  if(dp[j]>=a[i])
	  dp[j] = min(dp[j-a[i]]+1,dp[j]);                                                        
	  else 
	  dp[j] = dp[j-1]+1;
	  for(int i = 0;i < N;i++)
	  if(Max<dp[i])Max = dp[i];
	  cout << Max; 
	  return 0;
  }

2)大佬说ta是伪dp,还收敛不收敛的,让我一个高数不太好的人难受,有缘人自己看看吧 。

 我这个思路呢,怎么说呢,假的dp吧,我用了一个状态转移方式dp[i] = min(dp[(i + n – k) % n] + 1, dp[i – 1] + 1),就是要么从上一步走一步过来,要么从上k步走一步过来。因为他们的值是相关联的,所以每改一个值都要进行更新其他值,所以用了一个while(1),直到过程收敛,我用了一个sum来判断是不是收敛了,因为dp[i]要么减小,要么不变,所以当他们的和不变了,即收敛了,输出结果即可了。
 


#include<bits/stdc++.h>

using namespace std;

int dp[100005]; 

int main(){

	int n, k;

	cin>>n>>k;

	for(int i = 0; i < n; i++) dp[i] = i; // 初始化为多少分钟就要调多少次,默认一次调一分钟 

	for(int i = k; i < n; i += k) //从0出发,每+k步数就加一次 

		dp[i] = dp[i - k] + 1; 

	for(int i = k + 1; i < n; i += k) // 从1出发,每+k步数就加一次 

		dp[i] = dp[i - k] + 1;

	int sum = -1;

	while(1){ // 如果结果收敛,则停止循环,这里我们算他们的和,如果他们的步数和不变了,说明收敛了 

		int now_sum = 0;

		for(int i = 2; i < n; i++){

			now_sum += dp[i];

			dp[i] = min(dp[(i + n - k) % n] + 1, dp[i - 1] + 1);// 每一步都可以由上一步调k步或者1步得到 

		}

		if(now_sum == sum) break;

		sum = now_sum;

	}

	int maxdp = dp[0];

	for(int i = 0; i < n; i++){

//		cout<<dp[i]<<" ";

		maxdp = max(dp[i], maxdp);

	}

	cout<<maxdp<<endl;

	return 0;

}

 

——————— 
作者:Au-csdn 
来源:CSDN 
原文:https://blog.csdn.net/hzj1998/article/details/80492044 
版权声明:本文为博主原创文章,转载请附上博文链接!

BFS 

bfs吗,哇嘎哒。懒得写,还是看同一个大佬怎么说吧。

你可能会有疑问,为什么还是这个大佬。因为大佬就这么多,可能你这么努力,甚至别人在玩的时候还在看博客,但你成为大佬的几率还是很小,值得吗,还应该努力吗?答案是:努力,努力,再努力。直到真正变强的那天,请你务必给我点个关注,那我就有大佬关注了,嘻嘻。

再来另一种解法吧,广度搜索(bfs)解决的,因为广度搜索出来的步数一定是最小的。思路是从0出发,每次走1步或k步,一直这样,用一个vis[i]判断i是否走过。一直这样,直到走完所有点。


#include<bits/stdc++.h>

using namespace std;

queue<int> que;

int step[100005];

bool vis[100005];

int main(){

	int n, k;

	cin>>n>>k;

	for(int i = 0; i < n; i++){

		step[i] = 0;

		vis[i] = false;

	}

	que.push(0);

	step[0] = 0;

	vis[0] = true;

	while(!que.empty()){

		int now = que.front();

		que.pop();

		int one_step = (now + 1) % n;

		if(vis[one_step] == false){

			vis[one_step] = true;

			step[one_step] = step[now] + 1;

			que.push(one_step);

		}

		int k_step = (now + k) % n;

		if(vis[k_step] == false){

			vis[k_step] = true;

			step[k_step] = step[now] + 1;

			que.push(k_step);

		}

	}

	int max_step = step[0];

	for(int i = 0; i < n; i++)

		max_step = max(max_step, step[i]);

	cout<<max_step<<endl;

	return 0;

}

——————— 
作者:Au-csdn 
来源:CSDN 
原文:https://blog.csdn.net/hzj1998/article/details/80492044 
版权声明:本文为博主原创文章,转载请附上博文链接! 

 

 

 

 

今天的文章2018蓝桥杯比赛时间_第九届蓝桥杯[通俗易懂]分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/59137.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注