问题F:最少操作次数

问题 F: 最少操作次数

内存限制:128 MB时间限制:2.000 S

返回比赛提交提交记录侧边提交

题目描述

黑板上写着三个整数 A,B,C。

你可以以任意顺序执行以下两个操作任意次:

  • 选择其中两个数,并将这两个数减 1。

  • 将三个数都减 1。

你的目标是使黑板上的所有数字都为 0。

确定目标是否可以实现。如果是,请输出最少的操作次数。

输入

一行三个空格分隔的整数 A,B,C。

0≤A,B,C≤1018

输出

如果目标不可实现,请输出 −1。

否则,请输出最少操作次数。

样例输入 复制
2 2 3
样例输出 复制
3
提示

选择 A,C 减 1。数字变成 1,2,2。

选择 B,C 减 1。数字变成 1,1,1。

对所有数减 1。数字变成 0,0,0。

官方题解逻辑也大致一样.分享一下我的思路:

我的思路是挑两个数减一和三个数都减一这两种操作里,肯定是尽量挑三个数都减一能达到最少操作次数,因为三次前者才等于两次后者。所以我们要先处理三个数,使得它们相等。我们的处理操作就是挑两个数减一。

那么问题就变成怎么挑两个数减一,能够使得三个数相等?

很显然,我们可以用二元一次方程组去做,假设随便给出101 88 90三个数:

101-n-k=90-n;

101-n-k=88-k;

n+k显然就是我们要的操作次数;但不用解出该方程,因为我们又发现,我们最后还要加上三个数都减一的次数,也就是101-n-k(==90-n==88-k),加上n+k就是101,也就是三个数中最大的那个数。这道题的目标直接转变为求三个数的最大数即可。

同样我们需要讨论无法实现的情况,这里先直接给出结论,a>b+c.

也不用复杂的证明,倒着做;设a为最大值,a=b+c可以ac和ab共减1即可得0,那么a>b+c时a减完c减完b之后还有剩余。无法再进行。

萌新一般的AC代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
//三个数不是三角形不行(但是可以两边加和=最长)
//直接输出最大数

int main()
{
    long long a, b, c;
    cin >> a >> b >>c;
    if (a > b + c || b > a + c || c > b + a)
    {
        cout << -1 << endl;
        exit(0);
    }
    else
    {
        if (a > b && a > c)
            cout << a << endl;
        else if (b > a && b > c)
            cout << b << endl;
        else
            cout << c << endl;
    }
    return 0;
}

你可能感兴趣的:(C,buctoj,C++,算法,c++,c语言)