http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1246&judgeId=597896
题目来源: FaceBook HackerCup 比赛题
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
有n个罐子,有k个硬币,每个罐子可以容纳任意数量的硬币。罐子是不透明的,你可以把这k个硬币任意分配到罐子里。然后罐子被打乱顺序,你从外表无法区别罐子。最后罐子被编上号1-n。每次你可以询问某个罐子,如果该罐子里有硬币,则你可以得到1个(但你不知道该罐子中还有多少硬币),如果该罐子是空的,你得不到任何硬币,但会消耗1次询问的机会。你最终要得到至少c枚硬币(c <= k),问题是给定n,k,c,由你来选择一种分配方式,使得在最坏情况下,询问的次数最少,求这个最少的次数。
例如:有3个罐子,10个硬币,需要得到7个硬币,(n = 3, k = 10, c = 7)。
你可以将硬币分配为:3 3 4,然后对于每个罐子询问2次,可以得到6个硬币,再随便询问一个罐子,就可以得到7个硬币了。
Input
输入3个数:n,k,c (1 <= n <= 10^9, 1 <= c <= k <= 10^9)。
Output
输出最坏情况下所需的最少询问次数。
Input示例
4 2 2
Output示例
4
本以为是平均分突然发现平均分有些数据不行//45 64 54 67 错误代码示例:=.=
#include<iostream>
#include<string.h>
#include<algorithm>
#define maxn 1000000005
#define ll long long
using namespace std;
int main()
{
int n,c,k,sum=0,w=0;
cin>>n>>k>>c;
while(sum<c)
{
int q=k/n;
if((q*n) >= c&&w==0) {w=c;break;}
else
{
if(q==0)
{
int p=n%k;
w+=p+(c-sum);
break;
}
k-=q*n;
w+=q*n;
sum+=q*n;
}
}
cout<<w<<endl;
return 0;
}
//45 64 54 67 //18 10 8 16
就想肯定是分情况的,一种是能平铺玩的,还有一种是能找到尽量小的0,使得剩下的能全部平铺,这样结果就是 空罐子个数加上所询问的硬币个数,而最小的空罐子个数就是 用总的硬币数/(最少平均放的到最少罐子的个数+1)
#include<iostream>
#include<string.h>
#include<algorithm>
#define maxn 1000000005
#define ll long long
using namespace std;
int main()
{
int n,c,k,sum=0,w=0;
cin>>n>>k>>c;
int q=k/n;//每个罐子至少可以放q个
if((q*n)>=c) {w=c;}//当能平铺完肯定是平铺询问次数最小
else
{
w=(n-k/(q+1))+c;//不能平铺完,k/(q+1)表示 放q+1所需要的罐子,然后用抓空数+硬币数
}
cout<<w<<endl;
return 0;
}
//45 64 54 67 //18 10 8 16