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;
}

 

转载于:https://www.cnblogs.com/wjw2018/p/9320067.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值