HDU 1538-A Puzzle for Pirates

2024-03-10 21:50
文章标签 hdu 1538 puzzle pirates

本文主要是介绍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");elseprintf("%d\n",sum);}return 0;
}







这篇关于HDU 1538-A Puzzle for Pirates的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/795632

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时