取石子游戏

也许更好的阅读体验
D e s c r i p t i o n \mathcal{Description} Description

S o l u t i o n \mathcal{Solution} Solution

70分思路

f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示三堆石子分别为 i , j , k i,j,k i,j,k个石子时先手必胜还是先手必败 1 1 1为必胜 0 0 0为必败
由于石子的位置没有影响,所以 f [ i ] [ j ] [ k ] = f [ i ] [ k ] [ j ] = f [ j ] [ i ] [ k ] = f [ j ] [ k ] [ i ] = f [ k ] [ i ] [ j ] = f [ k ] [ j ] [ i ] f[i][j][k]=f[i][k][j]=f[j][i][k]=f[j][k][i]=f[k][i][j]=f[k][j][i] f[i][j][k]=f[i][k][j]=f[j][i][k]=f[j][k][i]=f[k][i][j]=f[k][j][i]
当一种状态可以转移成先手必败态时,该状态是先手必胜态
很明显,只要转移到先手必败态,那么对面就必败了
所以我们枚举后继状态然后看能不能转移到先手必败态,如能即为必胜态,否则就是必败态
再加点优化什么的
f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]是必败态,那么 f [ i ] [ j ] [ k + a ]   ( a &gt; 0 ) f[i][j][k+a] (a&gt;0) f[i][j][k+a] (a>0)就是必胜态(当然 a &lt; 0 a&lt;0 a<0也都是必败态,但是对算法没什么用处)
证明,若 a &gt; 0 a&gt;0 a>0,先手可以对 k k k拿走 a a a个石子就转移到必败态
那么我们先全部赋值为必胜态,然后当我们找到一个必败态后即可 b r e a k break break
用一个f[i][j]表示有没有两堆石子数为 i , j i,j i,j的必败态,如枚举到的石子堆包含了 i , j i,j i,j即可 b r e a k break break
另外,可对包含一个为 0 0 0的数据特殊对待,下面没有给出代码
下面是主要代码

int f[303][303];
int g[303][303][303];
memset(f,1,sizeof(f));
f[0][0][0]=0,g[0][0]=1;
for (int i=0;i<=100;++i)
	for (int j=i;j<=100;++j){
		if (!g[i][j]){
			for (int k=j;k<=100;++k){
				if (i+j+k<3)	continue;
				if (!g[i][k]&&!g[j][k]){
					f[i][j][k]=0;
					for (int p=1;(p<=i||p<=j||p<=k)&&!f[i][j][k];++p){
						if (p<=i)	f[i][j][k]|=!f[i-p][j][k];
						if (p<=j)	f[i][j][k]|=!f[i][j-p][k];
						if (p<=k)	f[i][j][k]|=!f[i][j][k-p];
						if (p<=i&&p<=j)	f[i][j][k]|=!f[i-p][j-p][k];
						if (p<=i&&p<=k)	f[i][j][k]|=!f[i-p][j][k-p];
						if (p<=j&&p<=k)	f[i][j][k]|=!f[i][j-p][k-p];
						if (p<=i&&p<=j&&p<=k)	f[i][j][k]|=!f[i-p][j-p][k-p];
					}
					f[i][k][j]=f[j][i][k]=f[j][k][i]=f[k][i][j]=f[k][j][i]=f[i][j][k];
					if (!f[i][j][k]){
						g[i][j]=g[j][i]=g[i][k]=g[k][i]=g[j][k]=g[k][j]=1;
						break;
					}
				}
			}
		}
	}

100分思路

上面的复杂度是 O ( n 4 ) O(n^4) O(n4),因为去枚举后继状态会枚举到非常多的重复状态,所以我们考虑由必败态反推必胜态
这样重复的状态就大大减少了,复杂度为 O ( n 3 ) O(n^3) O(n3)多一点

/******************************* Author:Morning_Glory LANG:C++ Created Time:2019年06月10日 星期一 09时35分36秒 *******************************/
#include <cstdio>
#include <fstream>
#include <cstring>
using namespace std;
const int maxn = 303;
//{{{cin
struct IO{
	template<typename T>
	IO & operator>>(T&res){
		res=0;
		bool flag=false;
		char ch;
		while((ch=getchar())>'9'||ch<'0')	 flag|=ch=='-';
		while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
		if (flag)	 res=~res+1;
		return *this;
	}
}cin;
//}}}
int T,x,y,z;
bool f[maxn][maxn][maxn];
inline void update (int a,int b,int c) { f[a][c][b]=f[b][a][c]=f[b][c][a]=f[c][a][b]=f[c][b][a]=f[a][b][c]; }
int main()
{
	cin>>T;
	f[0][0][0]=0;
	for (int i=0;i<=300;++i)
		for (int j=i;j<=300;++j)
			for (int k=j;k<=300;++k)
				if (!f[i][j][k])
					for (int p=1;i+p<=300||j+p<=300||k+p<=300;++p){
						if (i+p<=300)	f[i+p][j][k]=true,update(i+p,j,k);
						if (j+p<=300)	f[i][j+p][k]=true,update(i,j+p,k);
						if (k+p<=300)	f[i][j][k+p]=true,update(i,j,k+p);
						if (i+p<=300&&j+p<=300)	f[i+p][j+p][k]=true,update(i+p,j+p,k);
						if (i+p<=300&&k+p<=300)	f[i+p][j][k+p]=true,update(i+p,j,k+p);
						if (j+p<=300&&k+p<=300)	f[i][j+p][k+p]=true,update(i,j+p,k+p);
						if (i+p<=300&&j+p<=300&&k+p<=300)	f[i+p][j+p][k+p]=true,update(i+p,j+p,k+p);
					}
	while (T--){
		cin>>x>>y>>z;
		if (f[x][y][z])	printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

全部评论

相关推荐

想干测开的tomca...:让我来压力你!!!: 这份简历看着“技术词堆得满”,实则是“虚胖没干货”,槽点一抓一大把: 1. **项目描述是“技术名词报菜名”,没半分自己的实际价值** 不管是IntelliDoc还是人人探店,全是堆Redis、Elasticsearch、RAG这些时髦词,但你到底干了啥?“基于Redis Bitmap管理分片”是你写了核心逻辑还是只调用了API?“QPS提升至1500”是你独立压测优化的,还是团队成果你蹭着写?全程没“我负责XX模块”“解决了XX具体问题”,纯把技术文档里的术语扒下来凑字数,看着像“知道名词但没实际动手”的实习生抄的。 2. **短项目塞满超纲技术点,可信度直接***** IntelliDoc就干了5个月,又是RAG又是大模型流式响应又是RBAC权限,这堆活儿正经团队分工干都得小半年,你一个后端开发5个月能吃透这么多?明显是把能想到的技术全往里面塞,生怕别人知道你实际只做了个文件上传——这种“技术堆砌式造假”,面试官一眼就能看出水分。 3. **技能栏是“模糊词混子集合”,没半点硬核度** “熟悉HashMap底层”“了解JVM内存模型”——“熟悉”是能手写扩容逻辑?“了解”是能排查GC问题?全是模棱两可的词,既没对应项目里的实践,也没体现深度,等于白写;项目里用了Elasticsearch的KNN检索,技能栏里提都没提具体掌握程度,明显是“用过但不懂”的硬凑。 4. **教育背景和自我评价全是“无效信息垃圾”** GPA前10%这么好的牌,只列“Java程序设计”这种基础课,分布式、微服务这些后端核心课提都不提,白瞎了专业优势;自我评价那堆“积极认真、细心负责”,是从招聘网站抄的模板吧?没有任何和项目挂钩的具体事例,比如“解决过XX bug”“优化过XX性能”,纯废话,看完等于没看。 总结:这简历是“技术名词缝合怪+自我感动式凑数”,看着像“背了后端技术栈名词的应届生”,实则没干货、没重点、没可信度——面试官扫30秒就会丢一边,因为连“你能干嘛”都没说清楚。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务