ZOJ 3057 Beans Game题解

2024-06-07 07:08
文章标签 题解 zoj game beans 3057

本文主要是介绍ZOJ 3057 Beans Game题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目大意】:

    有三堆豆子a,b,c(0<a+b+c<=300)。TT和DD轮流从其中一堆拿走任意个豆子或从其中的两种拿走同样多的豆子,最后一个拿完的获胜。(TT先手)

【分析】:

    首先想到的是记忆化搜索,但是由于常数过大,以及空间复杂度的问题,改成利用“能操作成必败态的局面必为必胜态”的性质,改用常数更小的递推形式。具体请见代码(附记忆化搜索的代码和递推代码,只有递推能过

【代码1:记忆化搜索】:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 301
int A,B,C,rem[MAX][MAX][MAX];
int work(int a,int b,int c)
{if(rem[a][b][c]!=-1)   return rem[a][b][c];   if((a&&!b&&!c) || (!a&&b&&!c) || (!a&&!b&&c) || (a==b&&!c) || (a==c&&!b) || (c==b&&!a))return rem[a][b][c]=1;for(int i=1;i<=a;i++)if(!rem[a-i][b][c] || work(a-i,b,c)==0)return rem[a][b][c]=1;for(int i=1;i<=b;i++)if(!rem[a][b-i][c] || work(a,b-i,c)==0)return rem[a][b][c]=1;for(int i=1;i<=c;i++)if(!rem[a][b][c-i] || work(a,b,c-i)==0)return rem[a][b][c]=1;int limit;limit=a<b?a:b;for(int i=1;i<=limit;i++)if(!rem[a-i][b-i][c] || work(a-i,b-i,c)==0)return rem[a][b][c]=1;limit=b<c?b:c;for(int i=1;i<=limit;i++)if(!rem[a][b-i][c-i] || work(a,b-i,c-i)==0)return rem[a][b][c]=1;limit=a<c?a:c;for(int i=1;i<=limit;i++)if(!rem[a-i][b][c-i] || work(a-i,b,c-i)==0)return rem[a][b][c]=1;return rem[a][b][c]=0;	
}
int main()
{memset(rem,-1,sizeof(rem));while(scanf("%d%d%d",&A,&B,&C)!=EOF){if(work(A,B,C)==1)printf("1\n");else  printf("0\n");}return 0;
} 

【代码2:递推】:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 301
int A,B,C;
bool rem[MAX][MAX][MAX];
void work()
{for(int a=0;a<=300;a++)for(int b=0;b<=300;b++)for(int c=0;c<=300;c++)if(!rem[a][b][c]){for(int i=1;a+i<=300;i++)rem[a+i][b][c]=true;for(int i=1;b+i<=300;i++)rem[a][b+i][c]=true;for(int i=1;c+i<=300;i++)rem[a][b][c+i]=true;int limit=a<b?b:a;for(int i=1;limit+i<=300;i++)rem[a+i][b+i][c]=true;limit=a<c?c:a;for(int i=1;limit+i<=300;i++)rem[a+i][b][c+i]=true;limit=b<c?c:b;for(int i=1;limit+i<=300;i++)rem[a][b+i][c+i]=true;}
}
int main()
{work();while(scanf("%d%d%d",&A,&B,&C)!=EOF){printf("%d\n",rem[A][B][C]);}return 0;
} 


这篇关于ZOJ 3057 Beans Game题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038479

相关文章

数论ZOJ 2562

题意:给定一个数N,求小于等于N的所有数当中,约数最多的一个数,如果存在多个这样的数,输出其中最大的一个。 分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。 性质一:一个反素数的质因子必然是从2开始连续的质数。 性质二:p=2^t1*3^t2*5^t3*7

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

zoj 4624

题目分析:有两排灯,每排n个,每个灯亮的概率为p,每个灯之间互不影响,亮了的灯不再灭,问两排中,每排有大于等于m个灯亮的概率。 设dp[ i ][ j ]为第一排亮了i个灯,第二排亮了j个灯,距离目标状态的期望天数。显然 i >= m ,j >= m时 , dp[ i ][ j ] = 0 。 状态转移 : 第一排亮了a个灯,a 在[ 0 , n - i] 之间,第二排亮了b个灯 , b 在

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

ZOJ Monthly, August 2014小记

最近太忙太忙,只能抽时间写几道简单题。不过我倒是明白要想水平提高不看题解是最好的了。 A  我只能死找规律了,无法证明 int a[50002][2] ;vector< vector<int> > gmax , gmin ;int main(){int n , i , j , k , cmax , cmin ;while(cin>>n){/* g

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

fzu 2275 Game KMP

Problem 2275 Game Time Limit: 1000 mSec    Memory Limit : 262144 KB  Problem Description Alice and Bob is playing a game. Each of them has a number. Alice’s number is A, and Bob’s number i

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样