hdu 2149

题目概述:

巴什博奕,最后一次取的获胜

一堆里有N个,每次最多取M个,最少取1个

输入:

每行N,M,数据有多组,到EOF为止

限制:

0<N,M<1100

输出:

每行若干个整数或一个字符串,如果先手必败,则字符串为

none

如果先手必胜,输出首次取时所有必胜取法

两个整数之间有一个空格

多组输出之间没有空行

样例输入:

4 2
3 2
3 5

样例输出:

1
none
3 4 5

讨论:

题目原本的描述并没有如此直白,不过鉴于是个水题也没有什么理解难度就直接把模型提取好了,另外比较奇怪的一点是明明没有任何数组,却需要1.7mb的空间开销

简单说说巴什博奕的公式,N=(M+1)r+s,这里的N和M都是本题所用的总数和取的上限,r是一个任意数,s=N%(M+1),这个公式表明,如果s=0,则先手必败,否则必胜,如第二组样例,而必胜取法,在N<=M时,由于一次可以全部取走,只要首次在M的范围内一次取尽都可获胜,即第三组样例,如果N>M,一次无法取尽,首次取s个,如果对手取了k个,则只要保证再次到对手时还剩下(M+1)(r-1)个,即我方取走了M+1-k个,轮到对方时便总是t态,第一组样例即是如此

题解状态:

0MS,1712K,642 B,C++

#include<algorithm>
#include<string.h>
using namespace std;
#define INF 0x3f3f3f3f
#define maxx(a,b) ((a)>(b)?(a):(b))
#define minn(a,b) ((a)<(b)?(a):(b))
#define MAXN 1007

inline void fun(int N, int M)
{
	if (!(N % (M + 1)))//s=0,必败
		printf("none\n");//output
	else if (N <= M) {//可一次取尽
		bool f = false;
		for (int p = N % (M + 1); p <= M; p++) {
			if (f)
				printf(" ");//output//按题目描述,只有两个数之间才有空格,也算小技巧之一
			printf("%d", p);//output
			f = true;
		}
		printf("\n");//output//同时这种输出需要最后补上换行
	}
	else//不可一次取尽
		printf("%d\n", N % (M + 1));//output//这个数就是s
}
int main(void)
{
	//freopen("vs_cin.txt", "r", stdin);
	//freopen("vs_cout.txt", "w", stdout);

	int M, N;
	while (~scanf("%d%d", &N, &M)) {//input
		fun(N, M);
	}
}

EOF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值