不知道这个为什么是红题,让我们一起看看
2025-10-23 22:51:42
发布于:山东
13阅读
0回复
0点赞
前置知识:齐肯多夫(Zeckendorf)定理
内容:任何正整数都可以表示成若干个不连续的斐波那契数之和,这种和式称为齐肯多夫表述法,构造这种和式可以通过每次贪心选出最大的不超过它的斐波那契数。
证明(这里只考虑 不为斐波那契数的情况):
考虑数学归纳法,可以无脑得到
假设现在所有小于 的数都满足该定理,那么我们选择让 减去最大的不超过它的斐波那契数,显然新的 小于了旧的 ,故满足,至于为什么不会选重斐波那契数见下文
构造证明
考虑我们依次取
显然, ,因为
先看结论:
1.如果n为斐波那契数,则先手必输。
2.如果正整数 n 不为斐波那契数,则先手必赢。
证明:
1.先手不能一起全部取走,给后手的如果是一个斐波那契数,那么后手一定能给回来另一个斐波那契数,因为后手可以选择的数字的范围更大,久而久之先手一定会给后手一个非斐波那契数,然后看下一个证明
2.根据齐肯多夫定理,我们可以把n表示为 满足 为斐波那契数。。先手先取 ,显然后手没法一步取走 ,因为一定存在。我们假设先手足够聪明,那么先手一定可以通过拉扯来作为取走属于 的最后一个元素。同理我们对于每一个 最后的一个元素都是先手取走的,所以最后是先手赢。
最后是代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<cmath>
#define ll long long
#define int long long
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
#define rop(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,a,b) for(int i=(a);i>(b);--i)
using namespace std;
int iread(){int x=0,y=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}while('0'<=c&&c<='9'){x=(x<<3)+(x<<1)+(c^'0');c=getchar();}return x*y;}
ll lread(){ll x=0,y=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}while('0'<=c&&c<='9'){x=(x<<3)+(x<<1)+(c^'0');c=getchar();}return x*y;}
map<int,int> ma;
int a,b,c;
signed main(){int T=1;while(T--){
a=b=1;
c=a+b;
while(c<=10000000000ll){
ma[a]=ma[b]=ma[c]=1;
a=b;
b=c;
c=a+b;
}
int n;
while(1){
n=iread();
if(!n) break;
if(ma[n]) puts("Second win");
else puts("First win");
}
}return 0;}
全部评论 1
还是博弈大蛇
1周前 来自 广东
0













有帮助,赞一个