[POJ1143]Number Game
[POJ1143]Number Game
试题描述
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.)
输入
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.
输出
输入示例
输出示例
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的更多相关文章
- Number Game poj1143
Description Christine and Matt are playing an exciting game they just invented: the Number Game. The ...
- JavaScript Math和Number对象
目录 1. Math 对象:数学对象,提供对数据的数学计算.如:获取绝对值.向上取整等.无构造函数,无法被初始化,只提供静态属性和方法. 2. Number 对象 :Js中提供数字的对象.包含整数.浮 ...
- Harmonic Number(调和级数+欧拉常数)
题意:求f(n)=1/1+1/2+1/3+1/4-1/n (1 ≤ n ≤ 108).,精确到10-8 (原题在文末) 知识点: 调和级数(即f(n))至今没有一个完全正确的公式, ...
- Java 特定规则排序-LeetCode 179 Largest Number
Given a list of non negative integers, arrange them such that they form the largest number. For exam ...
- Eclipse "Unable to install breakpoint due to missing line number attributes..."
Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...
- 移除HTML5 input在type="number"时的上下小箭头
/*移除HTML5 input在type="number"时的上下小箭头*/ input::-webkit-outer-spin-button, input::-webkit-in ...
- 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.免费应用程序调试最 ...
- 有理数的稠密性(The rational points are dense on the number axis.)
每一个实数都能用有理数去逼近到任意精确的程度,这就是有理数的稠密性.The rational points are dense on the number axis.
- [LeetCode] Minimum Number of Arrows to Burst Balloons 最少数量的箭引爆气球
There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided ...
随机推荐
- Android学习总结(七)———— 本地广播
一.本地广播 2.1 基本概念 由于之前的广播都是全局的,所有应用程序都可以接收到,这样就很容易会引起安全性的问题,比如说我们发送一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停 ...
- 【2016新年版】年度精品 XP,32/64位Win7,32/64位Win8,32/64位Win10系统
本系统是10月5日最新完整版本的Windows10 安装版镜像,win10正式版,更新了重要补丁,提升应用加载速度,微软和百度今天宣布达成合作,百度成为win10 Edge浏览器中国默认主页和搜索引擎 ...
- POJ 2378 Tree Cutting (树的重心,微变形)
题意: 给定一棵树,n个节点,若删除点v使得剩下的连通快最大都不超过n/2,则称这样的点满足要求.求所有这样的点,若没有这样的点,输出NONE. 思路: 只需要拿“求树的重心”的代码改一行就OK了.因 ...
- codevs 1487 大批整数排序(水题日常)
时间限制: 3 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description !!!CodeVS开发者有话说: codevs自从换了评测机,新评测机的内存计算 ...
- Android计算器布局
Android(安桌)计算器布局实现 ——解决整个屏幕方案 引言: 学完了android布局的几种方式,做了一个android计算器. 我在网上搜索了这方面的资料,发现了布局都 ...
- leetcode_1053. Previous Permutation With One Swap
1053. Previous Permutation With One Swap https://leetcode.com/problems/previous-permutation-with-one ...
- 一条SQL语句在MySQL中是如何执行的
概览 本篇文章会分析下一个sql语句在mysql中的执行流程,包括sql的查询在mysql内部会怎么流转,sql语句的更新是怎么完成的. 一.mysql架构分析 mysql主要分为Server层和存储 ...
- history 路由且带二级目录的Apache配置
有多个项目目录的时候 由于项目不知一个,所以不得不为每一个项目建一个专有的文件夹,这就导致了在配置nginx的时候会出现二级目录 - step1: 修改 vue.config.js 添加配置 ...
- vue for循环中常见问题 之 求和(合计)
例:求后台返回数据this.dataInfo 中某个字段(item.totalSum)的和,只需添加computed,然后模板中直接可以使用totalSumAll (不需要再data中声明) comp ...
- luogu愚人节比赛划水记
先放链接:愚人节比赛 说好的 不毒瘤 呢?题目都太神奇了吧! 管理员的脑洞orz T1 这个可以说是蒙数据蒙出来的,直接输出"0",AC T2 本机房dalao成功发现" ...