Description

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.)

Input

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.

Output

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.

Sample Input

2 2 5
2 2 3
5 2 3 4 5 6
0

Sample Output

Test Case #1
The winning moves are: 2 Test Case #2
There's no winning move. Test Case #3
The winning moves are: 4 5 6

【题意】两个人玩游戏,给出2~20中的几个数,取出一个数后去掉该数,其倍数也去掉,已经去掉的数和当前的数相加的和如果存在数组中也去掉;

求先选哪些数会赢;

【思路】

状态压缩

要从一个状态里去掉某个位置的数  state&=~(1<<(i))

要给一个状态加入某个位置的数state|=(1<<i)

判断一个状态里是否包含某个位置的数 if(state&(1<<i))  为1则包含

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[<<];
int get_ans(int state,int x)
{
int tmp=state;
for(int i=x; i<=; i+=x)//将倍数去掉;
{
tmp&=~(<<(i-));
}
for(int i=; i<=; i++)//假设某个数在这个集合里,那么用它不断减去x, 如果得到的差值不在这个集合里,那么这个数是非法的,所以要去掉。
{
if(tmp&(<<(i-)))
for(int j=x; i-j->=; j+=x)
{
if(!(tmp&(<<(i-j-))))
{
tmp&=~(<<(i-));
break;
}
}
}
return tmp;
}
int dfs(int state)
{
if(dp[state]!=-) return dp[state];
for(int i=; i<=; i++)
{
if(state&(<<(i-)))
{
if(dfs(get_ans(state,i))==)//等于零说明没得选了,赢了
return dp[state]=;
}
}
return dp[state]=;
}
int main()
{
int cas=;
int a[],n;
while(scanf("%d",&n)!=EOF,n)
{
int state=;
memset(dp,-,sizeof(dp));
for(int i=; i<=n; i++)
{
scanf("%d",&a[i]);
state|=(<<(a[i]-));
}
printf("Test Case #%d\n",cas++);
if(!dfs(state)) printf("There's no winning move.");
else
{
printf("The winning moves are:");
for(int i=; i<=n; i++)
{
if(dfs(get_ans(state,a[i]))==)
printf(" %d",a[i]);
} }
cout<<endl<<endl;
}
return ;
}

Number Game_状态压缩的更多相关文章

  1. POJ 3254. Corn Fields 状态压缩DP (入门级)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Descr ...

  2. codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)

    B. Preparing Olympiad You have n problems. You have estimated the difficulty of the i-th one as inte ...

  3. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  4. SRM 513 2 1000CutTheNumbers(状态压缩)

    SRM 513 2 1000CutTheNumbers Problem Statement Manao has a board filled with digits represented as St ...

  5. ACM: HDU 5418 Victor and World - Floyd算法+dp状态压缩

    HDU 5418 Victor and World Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%I64d & ...

  6. [ACM_动态规划] 轮廓线动态规划——铺放骨牌(状态压缩1)

    Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, af ...

  7. codeforces 713A A. Sonya and Queries(状态压缩)

    题目链接: A. Sonya and Queries time limit per test 1 second memory limit per test 256 megabytes input st ...

  8. 状态压缩dp问题

    问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...

  9. Marriage Ceremonies(状态压缩dp)

     Marriage Ceremonies Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

随机推荐

  1. C#运算除法和求整

    在C#与法中,“/”除后所得的值的类型,跟他的除数和被除数的类型有关.如:                        int a=4;                        int b=5 ...

  2. OpenGL基础图形编程

    一.OpenGL与3D图形世界1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个充 ...

  3. boost 源码编译 的 Makefile.am写法备份

    include $(top_srcdir)/common.mk bin_PROGRAMS= lib_LIBRARIES= lib_LTLIBRARIES= lib_LTLIBRARIES+=libSt ...

  4. Spring MVC Controller中解析GET方式的中文参数会乱码的问题(tomcat如何解码)

    Spring MVC Controller中解析GET方式的中文参数会乱码的问题 问题描述 在工作上使用突然出现从get获取中文参数乱码(新装机器,tomcat重新下载和配置),查了半天终于找到解决办 ...

  5. mysql 索引长度限制

    MyISAM存储引擎引键的长度综合不能超过1000字节 InnoDB单列索引长度不能超过767bytes,联合索引还有一个限制是3072

  6. 使用了Windows Live Writer 写的博客

    <为什么标签不能正确的显示> 重新设置了之后再看看 停用了一些插件! ​ 偶然看到很多Blog都在说:“尝试连接到您的日志时出错:服务器响应无效 – 从日志服务器接收的对 blogger. ...

  7. java 面向对象编程 --第十二章 JDK常用类

    1.  系统类 java.lang包   System类 sys.out;sys.exit;sys.gc; sys.currentTimeMillis();----得到从1970-01-01到当前时间 ...

  8. HBase High Level Architecutre

  9. CentOS hadoop配置错误Incorrect configuration: namenode address dfs.namenode.servicerpc-address ...

    # ./sbin/start-all.sh                     This script is Deprecated. Instead use start-dfs.sh and st ...

  10. C#重启系统代码

    C#重启窗体代码 System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location ...