[POJ1143]Number Game

试题描述

Christine and Matt are playing an exciting game they just invented: the Number Game. The rules of this game are as follows. 
The players take turns choosing integers greater than 1. First, Christine chooses a number, then Matt chooses a number, then Christine again, and so on. The following rules restrict how new numbers may be chosen by the two players:

  • A number which has already been selected by Christine or Matt, or a multiple of such a number,cannot be chosen.
  • A sum of such multiples cannot be chosen, either.

If a player cannot choose any new number according to these rules, then that player loses the game. 
Here is an example: Christine starts by choosing 4. This prevents Matt from choosing 4, 8, 12, etc.Let's assume that his move is 3. Now the numbers 3, 6, 9, etc. are excluded, too; furthermore, numbers like: 7 = 3+4;10 = 2*3+4;11 = 3+2*4;13 = 3*3+4;... are also not available. So, in fact, the only numbers left are 2 and 5. Christine now selects 2. Since 5=2+3 is now forbidden, she wins because there is no number left for Matt to choose. 
Your task is to write a program which will help play (and win!) the Number Game. Of course, there might be an infinite number of choices for a player, so it may not be easy to find the best move among these possibilities. But after playing for some time, the number of remaining choices becomes finite, and that is the point where your program can help. Given a game position (a list of numbers which are not yet forbidden), your program should output all winning moves. 
A winning move is a move by which the player who is about to move can force a win, no matter what the other player will do afterwards. More formally, a winning move can be defined as follows.

  • A winning move is a move after which the game position is a losing position.
  • A winning position is a position in which a winning move exists. A losing position is a position in which no winning move exists.
  • In particular, the position in which all numbers are forbidden is a losing position. (This makes sense since the player who would have to move in that case loses the game.)

输入

The input consists of several test cases. Each test case is given by exactly one line describing one position. 
Each line will start with a number n (1 <= n <= 20), the number of integers which are still available. The remainder of this line contains the list of these numbers a1;...;an(2 <= ai <= 20). 
The positions described in this way will always be positions which can really occur in the actual Number Game. For example, if 3 is not in the list of allowed numbers, 6 is not in the list, either. 
At the end of the input, there will be a line containing only a zero (instead of n); this line should not be processed.

输出

For each test case, your program should output "Test case #m", where m is the number of the test case (starting with 1). Follow this by either "There's no winning move." if this is true for the position described in the input file, or "The winning moves are: w1 w2 ... wk" where the wi are all winning moves in this position, satisfying wi < wi+1 for 1 <= i < k. After this line, output a blank line.

输入示例


输出示例

Test Case #
The winning moves are: Test Case #
There's no winning move. Test Case #
The winning moves are: 6

数据规模及约定

见“输入

题解

这是一道博弈题,那么肯定是 dp 了。

一看数字这么少,自然想到状压 dp。根据博弈题的惯例,我们要枚举当前状态选举那个数字然后进行转移。

设 f(S) 表示当前剩余数字集合为 S,先手必胜还是必输。那么转移是枚举每个可以取的数字,假设我选择了数字 x,那么对于每一个数字 y,如果 y 没有在集合 S 中出现,则 x + y 这个数字也不能取了;同时注意,如果新产生了一个不能取的数,那么这个数 + x 也是不能取的(类似于对于这个集合 S 又做了一次无限背包);把所有不能取的数从状态 S 中去掉得到新的状态 tS 就可以转移了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 25
#define maxs 1048576 char str[maxn];
char* bin_(int x) {
int l = 0;
while(x) str[l++] = (x & 1) + '0', x >>= 1;
while(l < 19) str[l++] = '0';
str[l] = 0;
return str;
} int f[maxs];
int dp(int S) {
if(!S) return f[S] = 0;
if(f[S] >= 0) return f[S];
for(int i = 0; i < 19; i++) if(S >> i & 1) {
int x = i + 2, tS = S ^ (1 << i);
for(int j = 0; j < 19; j++)
if(j + x < 19 && !(tS >> j & 1) && (tS >> j + x & 1)) tS ^= (1 << j + x);
if(!dp(tS)) return f[S] = 1;
}
return f[S] = 0;
} int cnt, Ans[maxn]; int main() {
int kase = 0;
while(1) {
int n = read();
if(!n) break;
int S = 0;
for(int i = 1; i <= n; i++) S |= (1 << read() - 2);
memset(f, -1, sizeof(f));
printf("Test Case #%d\n", ++kase);
if(dp(S)) {
printf("The winning moves are: ");
cnt = 0;
for(int i = 0; i < 19; i++) if(S >> i & 1) {
int x = i + 2, tS = S ^ (1 << i);
for(int j = 0; j < 19; j++)
if(j + x < 19 && !(tS >> j & 1) && (tS >> j + x & 1)) tS ^= (1 << j + x);
if(!dp(tS)) Ans[++cnt] = x;
}
for(int i = 1; i <= cnt; i++) printf("%d%c", Ans[i], i < cnt ? ' ' : '\n');
putchar('\n');
}
else puts("There\'s no winning move.\n");
} return 0;
}

[POJ1143]Number Game的更多相关文章

  1. Number Game poj1143

    Description Christine and Matt are playing an exciting game they just invented: the Number Game. The ...

  2. JavaScript Math和Number对象

    目录 1. Math 对象:数学对象,提供对数据的数学计算.如:获取绝对值.向上取整等.无构造函数,无法被初始化,只提供静态属性和方法. 2. Number 对象 :Js中提供数字的对象.包含整数.浮 ...

  3. Harmonic Number(调和级数+欧拉常数)

    题意:求f(n)=1/1+1/2+1/3+1/4-1/n   (1 ≤ n ≤ 108).,精确到10-8    (原题在文末) 知识点:      调和级数(即f(n))至今没有一个完全正确的公式, ...

  4. Java 特定规则排序-LeetCode 179 Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  5. Eclipse "Unable to install breakpoint due to missing line number attributes..."

    Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...

  6. 移除HTML5 input在type="number"时的上下小箭头

    /*移除HTML5 input在type="number"时的上下小箭头*/ input::-webkit-outer-spin-button, input::-webkit-in ...

  7. iOS---The maximum number of apps for free development profiles has been reached.

    真机调试免费App ID出现的问题The maximum number of apps for free development profiles has been reached.免费应用程序调试最 ...

  8. 有理数的稠密性(The rational points are dense on the number axis.)

    每一个实数都能用有理数去逼近到任意精确的程度,这就是有理数的稠密性.The rational points are dense on the number axis.

  9. [LeetCode] Minimum Number of Arrows to Burst Balloons 最少数量的箭引爆气球

    There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided ...

随机推荐

  1. 设置office首字母不变大小的手段

    选项->校对—〉自动更正选项->“自动更正”页,句首字母大写,取消就行了

  2. codevs 1145 Hanoi双塔问题 2007年NOIP全国联赛普及组

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 给定A.B.C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的 ...

  3. ARC和MRC混合模式下的编译问题

    在一个支持ARC (Automatic Reference Counting)的项目中,有时候需要禁止其中几个文件使用ARC模式编译(比如你用了第三方不支持ARC的类库).这时就要点击工程文件,在ta ...

  4. strongSwan大坑一直重启(ubuntu)

    报错 Starting strongSwan 5.3.2 IPsec [starter]... charon (20533) started after 40 ms charon stopped af ...

  5. input提示文字;placeholder字体修改

    在很多网站上我们都看到input输入框显示提示文字,让我们一起来看看如果在input输入框中显示提示文字.我们只需要在<input>标签里添加:placeholder="提示文字 ...

  6. 激活 IDEA, PyCharm

    1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ http://ide ...

  7. python_111_动态导入模块

    lib下aa.py文件内容: class C: def __init__(self): self.name='alex' from lib import aa#正常导入 print(aa.C) 动态导 ...

  8. Windows MinGW 64-bit boost 踩坑

    >g++ -Wall -shared -g -DBUILD_DLL main.cpp -ID:\gcc\boost\include\boost-1_69 -LD:\gcc\boost\lib - ...

  9. Hibernate查询语句HQL8大特点

    Hibernate拥有一种功能非常强大的查询语言,这种语言被有意得与SQL非常相似,便于开发人员掌握.但不要被HQL的语法表面所迷惑,HQL完全是面向对象的,可以用来过程多态.继承.关联等关系. 1. ...

  10. javase(14)_java基础增强

    一.Eclipse的使用 1.在eclipse下Java程序的编写和run as,debug as,及java运行环境的配置. 2.快捷键的配置,常用快捷键: •内容提示:Alt + / •快速修复: ...