Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 三个数字中成对递减的最大数目_C++_Algorithm_Math - Fatal编程技术网

C++ 三个数字中成对递减的最大数目

C++ 三个数字中成对递减的最大数目,c++,algorithm,math,C++,Algorithm,Math,给出了3个非负整数a、b、c 在一次运算中,只有当两个整数没有变为负数时,我们才能从中减去1 在给定的操作不可行之前,我们必须找到最大可能的操作数 约束:1(1,0,7)->(0,0,6),答案是2 任何方法或证据都将非常有用 据我所知,我实际上已经编写了一个运行正常的代码,但我不知道它是否完全正确 #include <bits/stdc++.h> using namespace std; #define fastio ios_base::sync_with_stdio(0); c

给出了3个非负整数a、b、c

在一次运算中,只有当两个整数没有变为负数时,我们才能从中减去1

在给定的操作不可行之前,我们必须找到最大可能的操作数

约束:1(1,0,7)->(0,0,6),答案是2

任何方法或证据都将非常有用

据我所知,我实际上已经编写了一个运行正常的代码,但我不知道它是否完全正确

#include <bits/stdc++.h>
using namespace std;

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long 

int main(){
   fastio;
   int t; cin>>t;
   while(t--){
      LL a[3]; cin>>a[0]>>a[1]>>a[2];
      sort(a,a+3);
      if(a[0]+a[1]>=a[2]){
         LL ans = a[2] + (a[0]+a[1]-a[2])/2;
         cout<<ans;
      }
      else {
         LL ans = a[1] + min(a[0],a[2]-a[1]);
         cout<<ans;
      }
      cout<<"\n";
   }
}
#包括
使用名称空间std;
#定义fastio ios_base::与_stdio同步(0);中国领带(0)
#定义LL long long
int main(){
禁食;
int t;cin>>t;
而(t--){
LL a[3];cin>>a[0]>>a[1]>>a[2];
排序(a,a+3);
如果(a[0]+a[1]>=a[2]){
LL ans=a[2]+(a[0]+a[1]-a[2])/2;
难道这不只是:

对数字进行排序

1 2 3

total 0
减去第一个(并加到总数中),使第二个尽可能接近,而小于或等于第三个

0 2 2

total 1
减去第二个,再加上总数

0 0 0

total 3
?

功能f(arr){
arr.sort((a,b)=>a-b);
设[a,b,c]=arr;
const max_from_c=c-b;
如果(最大值从c>=a)
返回a+b;
设总=c中的最大值;
a=a-最大值(从c算起);
c=c-最大值(从c算起);
常数小于一半=数学楼层(a/2);
常数a<2?a:数学单元(a/2);
c=c-较大的一半;
总计=总计+较大的一半;
b=b-更小的一半;
总计=总计+较小的一半;
返回总计+数学最小值(b,c);
}
变量数组=[
[1,2,3], // 3
[1,1,8], // 2
[3,4,5], // 6
[1,1,1], // 1
[1,1,2], // 2
[2,1,2], // 2
[2,2,2], // 3
[3,3,2], // 4
[10000,10000,10000] // 15000
];
for(让数组的arr为){
log(JSON.stringify(arr));
控制台日志(f(arr));
控制台日志(“”);

}
我花了三次努力才把这个问题弄对。把这个问题误认为是动态规划问题是一个恶性循环

诀窍是认识到它可以在一个循环中解决,在这个循环中,您可以不断地从最小值到最大值排序
a、b、c
。然后评估数字适合哪个模式。要查找的模式包括:

  • 集合中1个或更少的正值:
    a=0、b=0、c=5
  • 集合中有2个正值和一个零:
    a=0,b=3,c=10
  • 3个不同的正值:
    a=5、b=11、c=88
  • 3个相同的正值:
    a=10,b=10,c=10
  • 3个正值,最小的两个相等:
    a=5,b=5,c=22
  • 3个正值,最大的两个相等:
    a=3,b=5,c=5
在您找出上面列表中的模式
a、b、c
之后,可以进行一些特定的快速缩减。其中许多将允许您在不需要进一步缩减集合的情况下打破循环。我认为下面的代码可以工作,因此它最多只在循环中迭代2次(或3次)因此,这是一个O(1)解

#include <iostream>
#include <algorithm>

using namespace std;

long long maxDeductions(long long a, long long b, long long c)
{
    long long total = 0;  // this is the running count of "deduction" steps made so far

    while (true)
    {
        long long deduction = 0;  // scratch variable for math

        // sort a,b,c into ascending order
        long long sorttable[3] = { a,b,c };
        sort(sorttable, sorttable + 3);
        a = sorttable[0];  // smallest
        b = sorttable[1];  // middle
        c = sorttable[2];  // largest

        // count the number of positive values among a,b,c    
        int positives = 0;
        positives += (a > 0);
        positives += (b > 0);
        positives += (c > 0);

        if (positives <= 1)
        {
            // Nothing left to do, we can break out of the loop
            break;
        }
        else if (positives == 2)
        {
            // When there are only two positives left
            // The number of deductions that can be express computed.
            // as the smaller of the remaining positive values, that is: b
            //
            // ASSERT: (b <= c) && (b > 0) && (c > 0)
            deduction = b;
            total += deduction;
            break;
        }
        else // three positives
        {
            if ((a != b) && (b != c))    // 3 positives, all different
            {
                // reduce the two larger values, b and c,  by the delta between b and a
                // this "b-a" amount is the number of deductions computed to  get the set a,b,c to have 
                // at least 2 identical numbers for the next set
                deduction = b - a;
                b = a;
                c -= deduction;
                total += deduction;
            }
            else if ((a == b) && (b == c)) // 3 positives, all the same
            {
                // when you have 3 identical values: N,N,N
                // It takes three steps to get to N-2,N-2,N-2
                // With a subtle tweak for odd vs even values of N, simple math can be used to 
                // deduce the remaining number of deductions

                if (a % 2) // odd
                {
                    deduction = ((a - 1) / 2) * 3 + 1;
                }
                else  // even
                {
                    deduction = (a / 2) * 3;
                }
                total += deduction;
                break;
            }
            else if (c == b)   // 3 positives, largest two are the same, equivalent to all different
            {
                deduction = b - a;
                b = a;
                c -= deduction;
                total += deduction;
            }
            else if (a == b)   // 3 positives, smallest two are the same
            {
                // this is the tricker one, but you can quickly see the pattern:
                // NNZ reduces in N*2 steps.  Example for N=5
                // 559 -> 548 -> 448 ->  437 -> 337 -> 326 -> 226 -> 215 -> 115 -> 104 -> 003
                // You can see every two reductions steps gets N,N,Z reduced to N-1,N-1,Z-1
                // Hence, exactly N*2 steps remaining
                total += (a * 2);
                break;
            }
        }

    }
    return total;
};
#包括
#包括
使用名称空间std;
长最大扣减(长a、长b、长c)
{
long total=0;//这是到目前为止进行的“扣除”步骤的运行计数
while(true)
{
long-long演绎=0;//数学的scratch变量
//将a、b、c按升序排序
长排序表[3]={a,b,c};
排序(排序表,排序表+3);
a=排序表[0];//最小
b=排序表[1];//中间
c=排序表[2];//最大
//计算a、b、c中正值的数量
正整数=0;
正值+=(a>0);
阳性+=(b>0);
阳性+=(c>0);
如果(正0)
扣除额=b;
总额+=扣除额;
打破
}
否则//3个积极因素
{
如果((a!=b)&&(b!=c))//3个正数,则都不同
{
//将两个较大的值b和c减去b和a之间的差值
//此“b-a”金额是为获得集合a、b、c而计算的扣减次数
//下一组至少有2个相同的数字
扣减=b-a;
b=a;
c-=扣除额;
总额+=扣除额;
}
否则如果((a==b)&&(b==c))//3个正数,都一样
{
//当您有3个相同的值时:N,N,N
//到达N-2,N-2,N-2需要三个步骤
//通过对N的奇偶值进行细微的调整,可以使用简单的数学计算
//推断剩余的扣减次数
if(a%2)//奇数
{
扣除额=((a-1)/2)*3+1;
}
否则//
{
扣除额=(a/2)*3;
}
总额+=扣除额;
打破
}
否则,如果(c==b)//3个正,则最大的两个是相同的,等于所有不同的
{
扣减=b-a;
b=a;
c-=扣除额;
总额+=扣除额;
}
否则,如果(a==b)//3个正,则最小的两个相同
{
//这是一个骗局,但你可以很快看到模式:
//NNZ以N*2个步骤减少。N=5的示例
// 559 -> 548 -> 448 ->  437 -> 337 -> 326 -> 226 -> 215 -> 115 -> 104 -> 003
//你可以看到每两个减少步骤,N,N,Z减少到N-1,N-1,Z-1
//因此,只剩下N*2个步骤
总数+=(a*2);
打破
}
}
}
返回总数;
};

我不理解第一个示例,为什么#include <iostream> #include <algorithm> using namespace std; long long maxDeductions(long long a, long long b, long long c) { long long total = 0; // this is the running count of "deduction" steps made so far while (true) { long long deduction = 0; // scratch variable for math // sort a,b,c into ascending order long long sorttable[3] = { a,b,c }; sort(sorttable, sorttable + 3); a = sorttable[0]; // smallest b = sorttable[1]; // middle c = sorttable[2]; // largest // count the number of positive values among a,b,c int positives = 0; positives += (a > 0); positives += (b > 0); positives += (c > 0); if (positives <= 1) { // Nothing left to do, we can break out of the loop break; } else if (positives == 2) { // When there are only two positives left // The number of deductions that can be express computed. // as the smaller of the remaining positive values, that is: b // // ASSERT: (b <= c) && (b > 0) && (c > 0) deduction = b; total += deduction; break; } else // three positives { if ((a != b) && (b != c)) // 3 positives, all different { // reduce the two larger values, b and c, by the delta between b and a // this "b-a" amount is the number of deductions computed to get the set a,b,c to have // at least 2 identical numbers for the next set deduction = b - a; b = a; c -= deduction; total += deduction; } else if ((a == b) && (b == c)) // 3 positives, all the same { // when you have 3 identical values: N,N,N // It takes three steps to get to N-2,N-2,N-2 // With a subtle tweak for odd vs even values of N, simple math can be used to // deduce the remaining number of deductions if (a % 2) // odd { deduction = ((a - 1) / 2) * 3 + 1; } else // even { deduction = (a / 2) * 3; } total += deduction; break; } else if (c == b) // 3 positives, largest two are the same, equivalent to all different { deduction = b - a; b = a; c -= deduction; total += deduction; } else if (a == b) // 3 positives, smallest two are the same { // this is the tricker one, but you can quickly see the pattern: // NNZ reduces in N*2 steps. Example for N=5 // 559 -> 548 -> 448 -> 437 -> 337 -> 326 -> 226 -> 215 -> 115 -> 104 -> 003 // You can see every two reductions steps gets N,N,Z reduced to N-1,N-1,Z-1 // Hence, exactly N*2 steps remaining total += (a * 2); break; } } } return total; };