NYOJ 取石子

取石子(一)

Description

一天,TT在寝室闲着无聊,和同寝的人玩起了取石子游戏,而由于条件有限,他/她们是用旺仔小馒头当作石子。游戏的规则是这样的。设有一堆石子,数量为N(1<=N<=1000000),两个人轮番取出其中的若干个,每次最多取M个(1<=M<=1000000),最先把石子取完者胜利。我们知道,TT和他/她的室友都十分的聪明,那么如果是TT先取,他/她会取得游戏的胜利么?

Input

第一行是一个正整数t,表示有t组测试数据
输入有不到1000组数据,每组数据一行,有两个数N和M,之间用空格分隔。

Output

对于每组数据,输出一行。如果先取的TT可以赢得游戏,则输出“Win”,否则输出“Lose”(引号不用输出)

Sample Input

2
1000 1
1 100

Sample Output

Lose
Win

巴什博弈

#include <iostream>
using namespace std;

int main(void)
{
	int t, n, m;
	cin >> t;
	while (t--){
		cin >> n >> m;
		if (n % (1 + m) != 0)
			cout << "Win" << endl;
		else
			cout << "Lose" << endl;
	}
	return 0;
}

取石子(二)

Description

小王喜欢与同事玩一些小游戏,今天他们选择了玩取石子。
游戏规则如下:共有N堆石子,已知每堆中石子的数量,并且规定好每堆石子最多可以取的石子数(最少取1颗)。
两个人轮流取子,每次只能选择N堆石子中的一堆,取一定数量的石子(最少取一个),并且取的石子数量不能多于该堆石子规定好的最多取子数,等哪个人无法取子时就表示此人输掉了游戏。
假设每次都是小王先取石子,并且游戏双方都绝对聪明,现在给你石子的堆数、每堆石子的数量和每堆石子规定的单次取子上限,请判断出小王能否获胜。

Input

第一行是一个整数T表示测试数据的组数(T<100)
每组测试数据的第一行是一个整数N(1<N<100),表示共有N堆石子,随后的N行每行表示一堆石子,这N行中每行有两个数整数m,n表示该堆石子共有m个石子,该堆石子每次最多取n个。(0<=m,n<=2^31)

Output

对于每组测试数据,输出Win表示小王可以获胜,输出Lose表示小王必然会败。

Sample Input

2
1
1000 1
2
1 1
1 1

Sample Output

Lose
Lose

HINT

注意下面一组测试数据
2
1 1
2 2
正确的结果应该是Win
因为小王会先从第二堆石子中取一个石子,使状态变为
1 1
1 2
这种状态下,无论对方怎么取,小王都能获胜。

巴什博弈+尼姆博弈
尼姆博弈是每堆都能取任意个(不能不取),而此题在每堆取的最大数目上加了限制,就变成了多堆的巴什博弈

#include <iostream>
using namespace std;

int main(void)
{
	int t, N, n, m, ans;
	cin >> t;
	while (t--){
		ans = 0;
		cin >> N;
		while (N--){
			cin >> n >> m;
			ans ^= n % (1 + m);
		}
		if (ans)
			cout << "Win" << endl;
		else
			cout << "Lose" << endl;
	}
	return 0;
}

取石子 (四)

Description

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

Input

输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,000。

Output

输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。

Sample Input

2 1
8 4
4 7

Sample Output

0
1
0

威佐夫博弈

#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
	int x, y;
	double t = (1 + sqrt(5)) / 2;
	while (cin >> x >> y){
		if (x > y)
			swap(x, y);
		if ((int)((y - x) * t) == x)
			cout << "0" << endl;
		else
			cout << "1" << endl;
	}
	return 0;
}

取石子(五)

Description

himdd最近很想玩游戏,于是他找到acmj和他一起玩,游戏是这样的:有一堆石子,两个人轮流从其中取走一定的石子,取走最后所有石子的人为赢家,不过得遵循如下规则:
1.第一次取不能取完,至少取1颗.
2.从第二次开始,每个人取的石子数至少为1,至多为对手刚取的石子数的两倍。
himdd事先想知道自己会不会赢,你能帮帮他吗?(每次himdd先手)

Input

有多组测试数据,每组有一个整数n(2<=n<2^64);

Output

himdd会赢输出Yes,否则输出No;

Sample Input

2
5
6

Sample Output

No
No
Yes

斐波那契博弈
比较坑的地方在于这道题会卡数,需要把n和数组开成unsigned long long
第93项之后的斐波那契数会大于 2 64 2^{64} ,所以查找的范围是在0——93
不得不说这道题的数据很强大T^T

#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;

ull f[100] = {0, 1};

int main(void)
{
	ull n;
	for (int i = 2; i <= 93; i++){
		f[i] = f[i - 1] + f[i - 2];
	}
	while (cin >> n){
		if (binary_search(f, f + 94, n))
			cout << "No" << endl;
		else
			cout << "Yes" << endl;
	}
	return 0;
}

取石子(六)

Description

最近TopCoder的PIAOYI和HRDV很无聊,于是就想了一个游戏,游戏是这样的:有n堆石子,两个人轮流从其中某一堆中任意取走一定的石子,最后不能取的为输家,注意: 每次只能从一堆取任意个,可以取完这堆,但不能不取。假设PIAOYI先取石子,请你帮他判断他是否能赢(假设他们取的过程中不发生失误,他们足够聪明)。

Input

第一行输入n,代表有n组测试数据(n<=10000) 以下每组测试数据包含两行:第一行:包含一个整数m,代表本组测试数据有m(m<=1000)堆石子; :第二行:包含m个整数Ai(Ai<=100),分别代表第i堆石子的数量。

Output

若PIAOYI赢输出“PIAOYI”,否则输出“HRDV”注意每组结果占一行。。

Sample Input

3
2
1 1
3
3 8 11
2
5 10

Sample Output

HRDV
HRDV
PIAOYI

尼姆博弈
这道题实在是太丧心病狂了,必须要用快速读入才能过
之前试了cin和scanf,结果都挂了

关于快速读入:https://www.cnblogs.com/newbiePWang/p/10192655.html

下面是几次提交的耗时情况

读入方法 耗时
cin 2002ms
cin关闭流同步 1457ms
scanf 1262ms
快读 651ms
#include <cstdio>
using namespace std;

inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
} // 这是能判负数的C++快读模板

inline void write(int x){
	if (x < 0) x = ~x + 1, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

int main(void)
{
	int t, n, a, ans;
	t = read();
	while (t--){
		ans = 0;
		n = read();
		while (n--){
			a = read();
			ans ^= a;
		}
		if (ans == 0)
			printf("HRDV\n");
		else
			printf("PIAOYI\n");
	}
	return 0;
}

取石子(七)

Description

Yougth和Hrdv玩一个游戏,拿出n个石子摆成一圈,Yougth和Hrdv分别从其中取石子,谁先取完者胜,每次可以从中取一个或者相邻两个,Hrdv先取,输出胜利着的名字。

Input

输入包括多组测试数据。 每组测试数据一个n,数据保证int范围内。

Output

输出胜利者的名字。

Sample Input

2
3

Sample Output

Hrdv
Yougth

题解链接:https://www.cnblogs.com/a1225234/p/4525727.html

#include <iostream>
using namespace std;

int main(void)
{
	int n;
	while (cin >> n){
		if (n <= 2)
			cout << "Hrdv" << endl;
		else
			cout << "Yougth" << endl;
	}
	return 0;
}

取石子(九)

Description

最近TopCoder的Yougth和Hrdv在玩一个游戏,游戏是这样的。
有n堆石子,两个人轮流从其中某一堆中任意取走一定的石子,最后不能取的为赢家,注意: 每次只能从一堆取任意个,可以取完这堆,但不能不取。
假设Yougth先取,输入赢了的人名字、

Input

第一行输入n,代表有n组测试数据(n<=10000) 以下每组测试数据包含两行:第一行:包含一个整数m,代表本组测试数据有m(m<=1000)堆石子; :第二行:包含m个整数Ai(Ai<=10000),分别代表第i堆石子的数量。

Output

若Yougth赢输出“Yougth”,否则输出“Hrdv”注意每组结果占一行。。

Sample Input

3
2
1 1
3
3 8 11
2
5 10

Sample Output

Yougth
Hrdv
Yougth

反尼姆博弈
在尼姆博奕中取完最后一颗石子的人为赢家
在反尼姆博奕中取完最后一颗石子的人为输家

题解:https://www.cnblogs.com/Nlifea/p/11745990.html

#include <cstdio>
using namespace std;

inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
} // 这是能判负数的C++快读模板

inline void write(int x){
	if (x < 0) x = ~x + 1, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

int main(void)
{
	bool flag;//是否存在大于1的石子堆 
	int t, n, a, ans;
	t = read();
	while (t--){
		flag = ans = 0;
		n = read();
		while (n--){
			a = read();
			ans ^= a;
			if (a > 1)
				flag = 1;
		}
		if (ans && flag || !ans && !flag)
			printf("Yougth\n");
		else
			printf("Hrdv\n");
	}
	return 0;
}
发布了177 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43772166/article/details/104109417