HDU 1538-A Puzzle for Pirates

A Puzzle for Pirates

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1207    Accepted Submission(s): 458


题目链接:点击打开链接


Problem Description
A bunch of pirates have gotten their hands on a hoard of gold pieces and wish to divide the loot. They are democratic pirates in their own way, and it is their custom to make such divisions in the following manner: The fiercest pirate makes a proposal about the division, and everybody votes on it, including the proposer. If 50 percent or more are in favor, the proposal passes and is implemented forthwith. Otherwise the proposer is thrown overboard, and the procedure is repeated with the next fiercest pirate. 
All the pirates enjoy throwing one of their fellows overboard, but if given a choice they prefer cold, hard cash, the more the better. They dislike being thrown overboard themselves. All pirates are rational and know that the other pirates are also rational. Moreover, no two pirates are equally fierce, so there is a precise pecking order — and it is known to them all. The gold pieces are indivisible, and arrangements to share pieces are not permitted, because no pirate trusts his fellows to stick to such an arrangement. It's every man for himself. Another thing about pirates is that they are realistic. They believe 'a bird in the hand is worth two in the bush' which means they prefer something that is certain than take a risk to get more, where they might lose everything. 

For convenience, number the pirates in order of meekness, so that the least fierce is number 1, the next least fierce number 2 and so on. The fiercest pirate thus gets the biggest number, and proposals proceed in the order from the biggest to the least. 

The secret to analyzing all such games of strategy is to work backward from the end. The place to start is the point at which the game gets down to just two pirates, P1 and P2. Then add in pirate P3, P4, ... , one by one. The illustration shows the results when 3, 4 or 5 pirates try to divide 100 pieces of gold. 



Your task is to predict how many gold pieces a given pirate will get.
 

Input
The input consists of a line specifying the number of testcases, followed by one line per case with 3 integer numbers n, m, p. n (1 ≤ n ≤ 10^4) is the number of pirates. m (1 ≤ m ≤ 10^7) is the number of gold pieces. p (1 ≤ p ≤ n) indicates a pirate where p = n indicates the fiercest one. 
 

Output
The output for each case consists of a single integer which is the minimal number of gold pieces pirate p can get. For example, if pirate p can get 0 or 1 gold pieces, output '0'. If pirate p will be thrown overboard, output 'Thrown'. 
 

Sample Input
 
 
3 3 100 2 4 100 2 5 100 5
 

Sample Output
 
 
0 1 98
Hint
Hint
The situation gets complicated when a few gold pieces were divided among many pirates.


题意:

一群海盗已经把手放在一堆金币上,并希望划分战利品。他们是以他们自己的方式进行划分,他们习惯于按照以下方式进行这样的分金币:
最凶猛的海盗提出关于分金币的建议,并且每个人都对它进行投票,包括提议者。如果有50%及以上的海盗赞成,该提案即通过并立即实施。否则,提议者被扔到海里,并且由下一个最凶猛的海盗进行提议。所有的海盗都想把他们的一位同伴(既提议者)扔到船外,但同时他们会通过对自己最有好处的提议,而且好处越大越好。同时他们不喜欢自己被抛在海里。所有海盗都是理性的,并且知道其他海盗也是理性的。而且,没有两个海盗同样凶恶,所以有一个精确的分金币顺序 - 它是所有人都知道的。金币是不可分割的,不允许分享的,因为没有海盗信任他的同伴。关于海盗的另一件事是他们是现实的。他们认为'十鸟在林不如一鸟在手',这意味着他们更喜欢明确获得的,而不是冒险获得更多,因为他们可能会失去一切。为了方便起见,按照温顺的顺序对海盗进行编号,最不凶恶的是1号,下一个是2号,等等。因此,最凶猛的海盗最先提出分配方案,及提案按照号码从最大到最小的顺序进行。你的任务是预测给定的海盗会得到多少金币。
现在有100枚金币
当有3个海盗时
他们所分配的金币数量如下
ID:1  2   3
   1  0   99
当有4个海盗时,他们所分配的金币数量如下
ID:1  2   3   4
   0  1   0   99
当有5个海盗时
他们所分配的金币数量如下
ID:1  2   3   4   5
   1  0   1   0   98


分析:

本题之前又一次拉比赛同学时遇见了,当时没有细看,之后同学讲了一下题意,感觉挺有意思,但是下去并没有分析本题的解法,果然,校赛又遇见了,jjjjjjjjj ·····

本题详解传送门:点击打开链接

因为大佬分析的很详细了,这里我不多做分析了,代码在关键的地方上写好详细的注释。


#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;

int main()
{
    int sum;///存所求人所得金币数目
    int n,m,p;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        sum=-1;///初始
        scanf("%d %d %d",&n,&m,&p);
        if(n<=2*m+1)///说明金币够分的情况
        {
            if(p==n)///如果正好是求最强大的人所得金币数
                sum=m-(n-1)/2;
            else if((p%2)==(n%2))///如果所求人的奇偶性与n相同,则都能得到一个金币
                sum=1;
            else///否则得话,就没有
                sum=0;
        }
        else
        {
            int bj=0;
            int a;
            for(int i=20;i>=1;i--)
            {
                if(n==2*m+(1<<i))/**如果正好是2*m+2^i,那么是稳定状态,只要将m个金币分出去就可以保命,
                所以具体是谁可能得到金币,我们不确定,这种情况所有的结构都是0**/
                {
                    sum=0;
                    bj=1;
                    break;
                }
                else if(n>(2*m+(1<<i))&&n<(2*m+(1<<(i+1))))///如果n在两种稳定的情况之间,那么记录下最小的稳定状态
                {
                    a=2*m+(1<<i);
                    break;
                }
            }
            if(bj==0)
            {
                if(p>a)///超过稳定状态的都是必死的
                    sum=-1;
                else///其余的都是稳定状态的
                    sum=0;
            }
        }
        if(sum==-1)
            printf("Thrown\n");
        else
            printf("%d\n",sum);
    }
    return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值