[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. iOS NSDate 常用日期相关函数的封装

    Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系. NSDate+Category.h 代码: #import & ...

  2. iOS之核心动画

    .将动画的所有方法封装到一个类里面 MyCAHelper.h #import <Foundation/Foundation.h> #import <QuartzCore/Quartz ...

  3. Does Little'law really applicable to apply performance model now?

    上次提到Little定律, 我也解释过它跟另外一个公式有一些内在的关系,但是其实我自己对LL在当前复杂架构系统中到底是怎么应用的也没有完整的想法,于是我在Linkedin上把这个问题抛了出来,没有想到 ...

  4. Windows系统下如何优化Android Studio

    Android Studio将是Android开发大势所趋. 安装Android Studio时需注意的细节: · 找到安装目录bin目录下idea.properties 最后一行加入:    dis ...

  5. CSS-学习笔记四

    1.*用于匹配任何的标记 2.>用于指定父子节点关系 3.E+F毗邻元素选择器,匹配所以紧随E元素之后的同级元素F 4.E~F匹配所以E元素之后的同级元素F 5.名称[表达式] [att=val ...

  6. haml scss转换编写html css的前期工作

    http://www.w3cplus.com/sassguide/install.html 先下载ruby $ gem sources $ gem sources --remove https://r ...

  7. 讲课笔记3——浮动、margin失效的问题、默认样式重置

    EO:搜索引擎优化,一般在网页里面只写一个h1标签,搜索引擎可以通过该h1标签里面的内容搜索你所写的网页(a标签和img标签最好写上title属性)标准写法: .logo { text-decorat ...

  8. NYOJ-1057-寻找最大数(三)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=1057 寻找最大数(三) 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描 ...

  9. 洛谷 P3958 奶酪

    谨以此题来纪念我爆炸的NOIp2017 这个题虽然很多人说是并查集,但是搜索也是毫无压力的,考场搜索细节写挂,爆了个不上不下的80分.今天无意看到这道题,终于AC 首先这道题要考虑一下精度问题,虽然出 ...

  10. 【数位dp】bzoj1799: [Ahoi2009]self 同类分布

    各种奇怪姿势的数位dp Description 给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数. Sample Input 10 19 Sample Output 3 HINT [约束条 ...