1 条题解

  • 0
    @ 2025-8-24 21:23:25

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Special_zyy
    **

    搬运于2025-08-24 21:23:24,当前版本为作者最后更新于2018-10-19 20:13:45,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    对于这道题,我们考虑什么样的状态(假设状态为(xxyy)假定y>=xy>=x)可以使当前操作的这个人胜利,显然,当x==yx==y时,当前操作的这个人必胜了;或者当y为x的倍数是,当前这个人也会获胜。除此之外呐?于是,我们接下来要考虑x>yx>y(去掉x==yx==y的情况)的情况。

    假设y=kx+zy=kx+z(z为余数)

    如果k>=2k>=2,那么该状态可以转移到(xx,yy-(kk-1)xx)即(xx,xx+zz),而(xx,xx+zz)(z要小于x的,因为z是余数),只能转移到(xx,zz)这一个状态,这个应该很好理解的。而(xx,yy)也可以直接转移到这个状态(yy-kxkx),所以不论(xx,xx+zz)这个状态还是其下一个状态(xx,zz)为必胜状态,(xx,yy)均可到达,所以当k>=2k>=2时,当前操作者必胜。

    如果k<2k<2呢?那我们只好转到下一个人操作,我们再尝试在下一个人的状态中判断这个人是否必胜。因为k<2k<2, 所以(xx,yy)只能转到(zz,xx)这个状态。那我们只要递归下去,知道找到必胜状态,返回当前操作者即可。

    代码如下:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    int m,n,q;
    //当前操作者为p,p为0时代表Stan操作,p为1时代表Ollie操作。
    int find(int x,int y,int p)
    {
    	if(x==y) return p;//返回胜者.
    	if(y/x>=2) return p;//返回胜者.
    	else return find(y-x,x,p^1);//向下一个状态查找.
    }
    int main()
    {
    	cin>>q;
    	for(int i=1;i<=q;i++)
    	{
    		cin>>m>>n;
    		if(m>n) swap(m,n);
    		if(find(m,n,0)==0) cout<<"Stan wins"<<endl;//如果返回0,胜者为Stan,反之则为Ollie.
    		else cout<<"Ollie wins"<<endl;
    	}
    	return 0;
    	
    }
    
    
    
    • 1

    信息

    ID
    289
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者