UESTC 766 乐乐和球球 博弈&&暴力(也可以不用暴力法)

来源:互联网 发布:飞天侠淘宝客网站程序 编辑:程序博客网 时间:2024/04/28 23:21

乐乐和球球

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

乐乐和岳蛤君在玩儿一个奇怪的游戏。

他们拿了N个一模一样的罐子,还有K个一模一样的小球,每个罐子里可以放下任意数量的小球,但是罐子外表被涂黑了,从外边观察是看不到每个

罐子里有几个小球的。

岳蛤君在游戏之前可以自己选择如何把K个小球分配到N个罐子里面去,但是分配之后,邪恶的乐乐会把罐子的顺序随机打乱。这样哪个罐子里有几

个小球就不是那么容易分辨出来了。

岳蛤君每次可以指向一个罐子,乐乐会打开这个罐子,如果里面是空的,乐乐会告诉岳蛤君,如果里面有球,乐乐就会拿出一个球,再把罐子盖上,

注意这个时候,乐乐不会告诉岳蛤君罐子里还剩几个球。

岳蛤君希望能在最坏情况下用尽量少的次数,拿出C个球出来。为了完成这个目的,他需要在游戏开始的时候,想一个优越的分配方法,告诉岳蛤君

最坏情况下的最少次数是多少吧!

Input

第一行一个整数T (T20),代表数据组数。

每组数据由一行组成,包括三个整数NKC1CK1000000,1N1000000  ),意义如题面所示。

Output

输出T行,每行输出最少的步数。

Sample input and output

Sample InputSample Output
23 6 43 4 4
45

Hint

第一组样例:一个可行的方案是三个罐子各放2个球,然后任选两个罐子各拿2次。

第二组样例:一个可行的方案是一个罐子为空罐,另外两个罐子各放两个球。这时,如果第一次运气不好指向了空罐子,接下来只需在剩下的两个罐

子里每个罐子各拿2次就可以了,所以无论如何,总步数不会超过5次。

My Solution

首先 N>=K 的情况应该是 拿空N-K 然后加上 C
当 N<K 如果 (K/N)*N>=C 则,为C
            如果 (K/N)*N<C 则,如果t*(N-i)>=C 则 i+C
                                            如果t*(N-i)<C 但是t*(N-i)+(t-1)*i>=C 则也是 i+C   //这里t*(N-i)+(t-1)*i可能>=K,但并不要紧,因为C<=K,则必定满足
                                            否则 i++
因为1e6*20*3 所以O(n)的暴力也基本上不超时

#include <iostream>#include <cstdio>//#define LOCALusing namespace std;int main(){    #ifdef LOCAL    freopen("a.txt","r",stdin);    #endif // LOCAL    int T,N,K,C,t;    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&N,&K,&C);        if((K/N)*N>=C) printf("%d",C);        else if(N>=K) printf("%d",N-K+C);               //该那空的N-K次全部那空,然后加上C        else{            for(int i=1;i<=N;i++){                      //找出那空的个数i,最优策略,就是那空的次数尽可能少                t=K/(N-i);                if(t*(N-i)>=C) {printf("%d",i+C);break;}                else if(t*(N-i)<C){                     //为了可以看的清楚一点,这里就分2次判断了                        if(t*(N-i)+(t-1)*i>=C) {printf("%d",i+C);break;} }            }        }        if(T) printf("\n");    }    return 0;}

谢谢

0 0