C++-分糖果 解题思路

【Horn Studio】编程专栏: 分糖果  解题思路

题目

题目描述

红太阳幼儿园有 nn 个小朋友, 你是其中之一。保证 n2n≥2 。
有一天你在幼儿园的后花园里发现无穷多颗糖果, 你打算拿一些糖果回去分给幼儿园的小朋友们。 由于你只是个平平无奇的幼儿园小朋友, 所以你的体力有限, 至多只能拿 RR 块糖回去。 但是拿的太少不够分的, 所以你至少要拿 LL 块糖回去。保证 nLRn≤L≤R 。 也就是说, 如果你拿了 kk 块糖, 那么你需要保证 LkRL≤k≤R 。
如果你拿了 kk 块糖, 你将把这 kk 块糖放到篮子里, 并要求大家按照如下方案分糖果:只要篮子里有不少于 nn 块糖果,幼儿园的所有 nn 个小朋友(包括你自己)都从篮子中拿走恰好一块糖, 直到篮子里的糖数量少 于 nn 块。此时篮子里剩余的糖果均归你所有一一这些糖果是作为你搬糖果的奖励。
作为幼儿园高质量小朋友, 你希望让作为你搬糖果的奖励的糖果数量(而不是你最后获得的总糖果数 量!)尽可能多; 因此你需要写一个程序, 依次输入 n,L,Rn,L,R, 并输出你最多能获得多少作为你搬糖果的奖 励的糖果数量。

输入

输入一行, 包含三个正整数 $n, L, R$, 分别表示小朋友的个数、糖果数量的下界和上界。

输出

输出一行一个整数,表示你最多能获得的作为你搬糖果的奖励的糖果数量。

样例输入 复制

7 16 23

样例输出 复制

6

提示

对于所有数据, 保证 2nLR1092≤n≤L≤R≤109 。

来源

思路

双做法:

1.暴力

只需要判断一下r-小于等于l的n的倍数中最大的数

用ans来记录一下 ans=r-(l/n*n);

如果ans>=n就肯定可以带回去<n中最大的糖果数目也就是n-1,不然ans就是它最大能带走的糖果数目

果然,复杂度是O(R-L),绝对tle!所以,我们需要转化一下……

2.数学思想(普通)

首先看到十分恐怖的数字,RL1e9,我们需要使用数学思想……

只需要判断一下r-小于等于l的n的倍数中最大的数

用ans来记录一下 ans=r-(l/n*n);

如果ans>=n就肯定可以带回去<n中最大的糖果数目也就是n-1,不然ans就是它最大能带走的糖果数目

 这并不会tle,也是其中一种办法。

3.数学思想(精简)

先尝试将余数补到n-1,如果超过r,那么结果就是r mod n,否则就是n-1。

 

代码 暴力

#include<bits/stdc++.h>
using namespace std;
int n,l,r;
int ans=-1;
int main(){
	scanf("%d%d%d",&n,&l,&r);
	for(int i=r;i>=l;i--){
		int k=i;
		while(k-n>0){
			k-=n;
		}if(k!=n) ans=max(ans,k);
	}printf("%d",ans);
	return 0;
} 
//12345code佐助题库提交结果:TLE 18%,超时3个点

代码 数学思想1:

 

#include<bits/stdc++.h>
using namespace std;
long long n,l,r,ans;
int main() {
	scanf("%lld%lld%lld",&n,&l,&r);
	ans=r-(l/n*n);
	if(ans>=n) {
		printf("%lld",n-1);
	} else {
		printf("%lld",ans);
	}
	return 0;
}//12345code佐助题库提交结果:AC

代码 数学思想2:

#include<bits/stdc++.h>
using namespace std;
int n,l,r;
int main(){
	cin>>n>>l>>r;
	cout<<min(r,l+(n-1-l%n))%n;
	return 0;
}

彩蛋

posted @ 2022-05-21 19:43  冯子坤  阅读(2433)  评论(1编辑  收藏  举报