zoukankan      html  css  js  c++  java
  • 【欧几里德的游戏】

    这道题好神仙啊

    我们推一下(SG)函数

    显然答案就是(SG(n,m))(SG(n,m)=0)则先手败,否则先手胜

    首先几个非常明显的地方(SG(n,0)=0),这是显然的,上来就面对了必败状态

    之后看看(SG)是如何转移的

    [SG(n,m)=mex{SG(n-m,m,SG(n-2*m,m)...SG(m,n\%m))} ]

    (mex)是基于集合的操作,(mex(S)={min(x)in N|x otin S}),也就是不属于集合(S)的最小自然数

    非常显然的是

    [SG(n-m,m)=mex{SG(n-2*m,m),SG(n-3*m,m)...SG(m,n\%m)} ]

    之后会惊奇的发现好像我们知道了(SG(m,n\%m))就可以推所有了

    分类讨论一波

    如果(SG(m,n\%m)=1),那么由于(SG(m,n\%m+m)=mex{SG(m,n\%m)}),所以这个时候(SG(m,n\%m+m)=0),于是(SG(n,m)=1)

    如果(SG(m,n\%m)=0),那么(SG(m,n\%m+m)=1),所以非常显然(SG(n,m)=1)

    但是这一切的前提就是(SG(m,n\%m+m))存在,如果(m<=2*n),那么(SG(n,m))就直接等于(SG(m,n\%m))了,也就是(SG(n,m)=SG(m,n\%m)igoplus1)

    于是一个类似于(gcd)的迭代就好了

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline LL read()
    {
    	char c=getchar();
    	int x=0;
    	while(c<'0'||c>'9')	c=getchar();
    	while(c>='0'&&c<='9')
    		x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x;
    }
    int T;
    LL n,m;
    inline int SG(LL n,LL m)
    {
    	if(!m) return 0;
    	if(n>=m*2) return 1;
    	return 1^SG(m,n%m);
    }
    int main()
    {
    	T=read();
    	while(T--)
    	{
    		n=read(),m=read();
    		if(SG(max(n,m),min(n,m))) puts("Stan wins");
    			else puts("Ollie wins");
    	}
    	return 0;
    }
    
  • 相关阅读:
    第一次个人项目【词频统计】——PSP表格
    第一次个人项目【词频统计】——需求分析,代码规范,设计思路
    第一次个人项目【词频统计】——测试样例分析&性能分析
    PHP5 构造函数
    简单的NT框架
    今天开始学内核
    人生感悟
    (十四)网络层OSPF协议
    (十三)网络层RIP协议报文格式
    (十一)网络层ICMP
  • 原文地址:https://www.cnblogs.com/asuldb/p/10205759.html
Copyright © 2011-2022 走看看