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