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;
    }
  • 相关阅读:
    终于以一个ACMer的名义开通博客了。。
    Struts学习笔记一
    Matplotlib画图
    设计模式第一集——策略模式
    Hibernate学习笔记
    在linux下加python path【转】
    linux学习笔记
    C#3.0初体验
    asp.net中使用ffmpeg
    常用的正则表达式(经典)
  • 原文地址:https://www.cnblogs.com/wjw2018/p/9320067.html
Copyright © 2011-2022 走看看