取石子游戏

也许更好的阅读体验
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;
}

全部评论

相关推荐

03-26 08:58
已编辑
门头沟学院 Java
ttl:&nbsp;3.19一面晚上过3.20二面3.23oc3.25offerbase:末9有一段中小厂实习一面面经:(总体时长一个小时二十分钟左右没什么八股,主要都是问项目和场景题1.实习(问了有四十分钟,感觉面试官很看重实习这一块,一直在拷打,问到后面我都要疯了,好在准备得比较充分1️⃣用的是什么中间件,有参与技术选型吗,实习的项目里为什么选这个RabbitMQ而不是kafka,为什么不用RocketMQ,为什么放弃异步,自己的项目里面使用的是kafka,那你觉得项目和实习的中间件选型有差异的原因是什么,他们之间的区别在哪里,底层的原因知道吗(高柱到这里已经快疯了,但是硬着头皮答完了,主要是从一致性吞吐量和框架的契合度答,面试官说答得挺好的,应该是没什么问题,这一块就问了快半个小时,到这里我已经快疯了2️⃣项目怎么对接上下游3️⃣介绍项目的难点重点4️⃣微服务(高柱实习是单体项目没涉及这一块5️⃣Redis的使用2.项目:1️⃣智能客服是怎么应用在项目里的(langchain4j➕rag➕functioncalling)2️⃣RAG了解多少3️⃣文本向量化的难点是什么,了解哪些大模型的知识(我一点不懂,纯瞎扯,但貌似扯对了4️⃣对ai的态度是什么,aicoding相关5️⃣怎么保证多节点下Caffeine缓存里面数据都是一致的(答的是短ttl,面试官不是很满意,但是我确实不太懂这个怎么保证,后来查了还是不懂怎么保证6️⃣Redis的使用,和你的实习项目的使用有区别吗,还有一些引申问题3.八股(含量不高,就是走个过场1️⃣进程的内存布局2️⃣Redis三剑客3️⃣微服务相关知识(高柱已经忘得差不多了…勉强答上来4️⃣JVM5️⃣线程状态6️⃣线程安全,在你的实习项目里怎么保证线程安全的(又绕回来了4.智商题找异常球5.手撕:1️⃣五道sql,不难2️⃣力扣不重叠的滑动窗口数组,贪心➕双指针秒了强度拉满了这个一面,高柱到后面人都是傻的二面面经:(就半个小时实习拷打,简历上写了几点就问了几点,问完就结束了,无手撕
查看19道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 大厂实习和小厂实习最大的区别是什么? #
2477次浏览 20人参与
# 参加完秋招的机械人,还参加春招吗? #
119953次浏览 761人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
18847次浏览 309人参与
# 牛友の3月总结 #
1881次浏览 28人参与
# 这些公司卡简历很严格 #
95210次浏览 417人参与
# 面试被问到不会的问题,你怎么应对? #
692次浏览 8人参与
# 米连集团26产品管培生项目 #
14502次浏览 291人参与
# 拼多多工作体验 #
52687次浏览 342人参与
# 研究所VS国企,该如何选 #
259071次浏览 2013人参与
# 通信硬件知识分享 #
48139次浏览 538人参与
# 找AI工作可以去哪些公司? #
17113次浏览 755人参与
# 从事AI岗需要掌握哪些技术栈? #
14951次浏览 850人参与
# 你做过最难的笔试是哪家公司 #
47513次浏览 762人参与
# 实习最想跑路的瞬间 #
130959次浏览 740人参与
# 金三银四,你的春招进行到哪个阶段了? #
24583次浏览 297人参与
# 说说你知道的学历厂 #
391012次浏览 1379人参与
# AI面会问哪些问题? #
36247次浏览 1080人参与
# 想给25届机械人的秋招建议 #
47743次浏览 251人参与
# 机械人避雷的岗位/公司 #
62887次浏览 395人参与
# 大厂无回复,继续等待还是奔赴小厂 #
343363次浏览 1988人参与
# 滴!实习打卡 #
814713次浏览 6858人参与
# 我心目中的理想工作是这样的 #
100878次浏览 907人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务