您的位置:首页 > 其它

HDOJ2897(巴什博弈变形-找规律)

2013-07-12 09:21 330 查看
这道题目乍一看像是巴什博弈,仔细斟酌的话,我们可以发现,这种博弈是可以找到规律的:先说题目:Problem Description每行有三个数字n,p,q,表示一堆硬币一共有n枚,从这个硬币堆里取硬币,一次最少取p枚,最多q枚,如果剩下少于p枚就要一次取完。两人轮流取,直到堆里的硬币取完,最后一次取硬币的算输。对于每一行的三个数字,给出先取的人是否有必胜策略,如果有回答WIN,否则回答LOST。[align=left]Sample Input[/align]
7 2 46 2 4[align=left]Sample Output[/align]
LOSTWIN这样我们可以这样考虑:
假设先取者为A,后取者为B,初始状态下有石子n个,除最后一次外其他每次取得石子个数必须在[p,q]之间。 
1):若当前石子共有n = (p+q) * r个,则A必胜,必胜策略为:A第一次取q个,以后每次若B取K个,A取(p+q-k)个,如此下去最后必剩下p个给B,所以A必胜。 
2)若n = (p+q)* r + left个(1 < left <= p)B必胜,必胜策略为:每次取石子活动中,若A取k个,则B去(p+q-k)个,那么最后剩下left个给A,此时left <= p,所以A只能一次去完,B胜。 
3)若n = (p+q) * r + left个(p < left <= q),则A必胜,必胜策略为:A第一次取t(1 < left – t < = p)个,以后每次B取k个,则A取(p+q-k)个,那么最后留下1 < left – t <= p给B,则A胜。(也就相当于当A取得时候,他可以把当前局势变为第2种的,即让B面对必败态,这时候的原理和2)就一样了
好了,就是简单的取余^-^上代码:#include <iostream>#include <cstdio>#include <string>#include <string.h>#include <map>#include <vector>#include <cstdlib>#include <cmath>#include <algorithm>#include <cmath>#include <queue>#include <set>#include <stack>using namespace std;int min(int a, int b){if(a<=b)return a;return b;}int max(int a, int b){if(a>=b)return a;return b;}double min(double a, double b){if(a<=b)return a;return b;}double max(double a, double b){if(a>=b)return a;return b;}int main(){int n, p, q;while(scanf("%d%d%d", &n, &p, &q)!=EOF){int left = n%(p+q);if(left == 0)printf("WIN\n");else{if(left > 0 && left <= p)printf("LOST\n");elseprintf("WIN\n");}}return 0;}努力努力...
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息