zoukankan      html  css  js  c++  java
  • A Boring Game

    1539: A Boring Game

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 3  解决: 3
    [提交][状态][讨论版][命题人:外部导入]

    题目描述

    Alice has nothing to do,so she decided to paly a game. Firstly, she has three heaps of stone. The number of three heaps of stone are n1, n2, n3, respectively. At each round, she can choose two piles from the three heaps of stone, and then take a stone from each of the two piles to the heap not been choosed. For example, n1=1, n2=2, n3=3. After the first round, it can become n1=0, n2=1, n3=5 or n1=0, n2=4, n3=2 or n1=3, n2=1, n3=2. The game will end if and only if two heap of stones are empty. Now, Alice wants you to calculate the minimum rounds before the end of game.

    输入

    There are at most 100000 cases. For each line, there are three integer n1, n2, n3(1<=ni<=10000, i=1,2,3).

    输出

    For each case, print the minimum rounds. If the game will not end, print "Oh, my God!".

    样例输入

    1 2 3
    1 2 2

    样例输出

    Oh, my God!
    2


    解题思路:首先考虑暴力搜索,这时必须要开一个vis数组来标记每种情况是否搜索过,但发现题目给出n的范围是在1-10000间,三维数组占用的空间是10000*10000*10000,会超内存,所以就不能用暴力搜索来做。
    换一种思路,可以找规律,设三堆石头石头的初始数量分别为A,B,C,从A,B中拿出一块石头给C的回合有x回,从A,C中拿出一块石头给B的回合有y回,从B,C中拿出一块石头给A的回合有z回,假设经历了x+y+z回合之后,有两堆石头的数量相等了,即游戏可以结束,便得到三个等式,化简后可以发现任意两堆石头的差一定是三的倍数,所以公式就找出来了。
    证明过程如下图:

    #include <bits/stdc++.h>
    using namespace std;
    
    int Min=999999;
    bool flag=false;
    
    bool check(int x,int y,int z)
    {
        if(x==y||x==z||y==z)//如果有两堆石头数量相等直接输出
        {
            if(x==y||x==z)Min=x;
            else if(y==z)Min=y;
            return true;
        }
        int Maxn=(x>y?x:y)>z?(x>y?x:y):z;
        int Minm=(x<y?x:y)<z?(x<y?x:y):z;
        int Medi=x+y+z-Maxn-Minm;
        for(int j=0;j<=(Maxn-Minm)/3+0.5;++j)//判断是否可以结束游戏
        {
            if(Minm+3*j==Medi)
            {
                if(Medi<Min)Min=Medi;
                flag=true;
            }
            else if(Minm+3*j==Maxn)
            {
                if(Maxn<Min)Min=Maxn;
                flag=true;
            }
            else if(Medi+3*j==Maxn)
            {
                if(Maxn<Min)Min=Maxn;
                flag=true;
            }
        }
        if(flag)return true;
        else return false;
    }
    
    int main()
    {
        int a,b,c;
        while(cin>>a>>b>>c)
        {
            Min=999999;
            flag=false;
            if(check(a,b,c))cout<<Min<<endl;
            else cout<<"Oh, my God!"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【解决】Windows7任务栏输入法图标无法显示
    【解决】任务栏中找不到语言栏
    SQL Server中根据起始星期计算星期数和周次数的函数
    SharePoint 2010 中如何配置同步配置文件
    如何禁止Windows系统自动安装驱动
    [要点总结]SharePoint 2010:如何配置表单认证(FBA)
    【解决】如何升级网站集内容数据库
    [解决]Office 2010不能同步文件到SharePoint
    羽毛球比赛规则简略版
    [转]SharePoint 2013中如何恢复“用不同用户登录”链接
  • 原文地址:https://www.cnblogs.com/wjw2018/p/9320067.html
Copyright © 2011-2022 走看看