下面的代码接受一个整数t,然后再接受3个整数t次,并返回可以同时从两个不同整数中减去1的最大次数,而当只剩下0以上的1个整数时,程序停止。我已经解决了这个问题,但我想降低代码的时间复杂度,但我不知道怎么做。
#include <bits/stdc++.h>
using namespace std;
int main() {
long long t, r, g, b, arr[1000], count = 0;
bool isMax=true;
cin >> t;
for (long long i = 0; i < t; i++) {
cin >> r >> g >> b;
arr[0] = r;
arr[1] = g;
arr[2] = b;
for (long long j = 0; j < 3; j++) {
for (long long k = 0; k < 2; k++) {
if (arr[k] > arr[k + 1]) {
long long a = arr[k];
long long b = arr[k + 1];
arr[k] = b;
arr[k + 1] = a;
}
}
}
count = 0;
if (arr[2] == 1) {
cout << 1 << endl;
} else if (arr[0] + arr[1] <= arr[2]) {
cout << arr[0] + arr[1] << endl;
} else {
while (arr[0] > 0) {
while (isMax && arr[0] > 0) {
arr[2]--;
arr[0]--;
count++;
if (arr[2] < arr[1]) {
isMax = false;
}
}
while (!isMax && arr[0] > 0) {
arr[1]--;
arr[0]--;
count++;
if (arr[1] < arr[2]) {
isMax = true;
}
}
}
while (arr[2] > 0 && arr[1] > 0) {
arr[2]--;
arr[1]--;
count++;
}
cout << count << endl;
}
}
}
如何在不使用所有这些增加时间复杂度的循环的情况下获得相同的输出?
编辑:我不想我的代码为我重新编写,这是家庭作业,我想要的是提示和帮助,这样我就可以减少时间复杂性,我不知道怎么做。
编辑2:在我的算法中,我按升序对3个数字进行排序,然后使用while循环检查最小的数字(s/arr[0])是否正确
我不确定我是否正确理解了这个问题,但如果你想知道从三元素集中的两个元素中减去1
直到达到零的最大次数,我相信答案应该与找到集合的中值元素相同。例如,如果我有一套
10 20 30
如果我总是选择从子集{20,30}
中减去,那么我能减去1的最大次数是20次,而如果我总是选择从子集{10,20}
中减去,那么最小次数是10
。
希望这有帮助!(假设我没有完全误解这个问题)
编辑:
在澄清评论之后,我相信您需要做的就是在非最大元素和最大元素之间找到最小值。考虑以下示例:
例如,如果给你一个集合{80,10,210}
,你的问题的答案是90,因为我们可以从子集{80,10
}中减去10,留下{70,0,210}
,我们可以从子集{70,210}
中进一步减去70,留下{0,0140}
,在那里我们不能执行更多的操作。我们用1进行了80次10=90的减法运算,在这种情况下,max=210,min med=90
另一方面,考虑集合{2,2,2}
。我们可以从子集{2,2}
中减去2,留下{0,0,2}
,在那里我们不能执行更多的操作。在这种情况下,我们通过1 Max=2和min med=4执行了2次减法
最后一个例子:考虑集合{2,3,5}
。我们可以从子集{2,3}
中减去2,留下{0,1,5}
,我们可以从子集{1,5}
中减去1,从而得到{0,0,4}
,在那里我们不能执行更多的操作。在这种情况下,我们通过1 Max=5和min med=5执行了2 3=5减法
如果您继续以这种方式执行示例,您应该能够说服自己解决方案总是最小(最大,最小中值)。
假设你的代码是正确的,你可以精确地检查你的循环在做什么,并从数学上看它们。
if ( arr[2] == 1 ) {
cout << 1 << endl;
} else if ( arr[0] + arr[1] <= arr[2] ) {
cout << arr[0] + arr[1] << endl;
} else {
while ( arr[0] > 0 ) {
if ( arr[2] > arr[1] ) {
long long min = std::min( std::min( arr[0], arr[2] ), arr[2] - arr[1] + 1 );
arr[0] -= min;
arr[2] -= min;
count += min;
} else {
long long min = std::min( std::min( arr[0], arr[1] ), arr[1] - arr[2] + 1 );
arr[0] -= min;
arr[1] -= min;
count += min;
}
}
count += std::min( arr[2], arr[1] );
cout << count << endl;
}
假设你的程序是正确的,他会对我尝试的所有输入产生相同的结果。
我不确定我是否正确理解了这个问题。但如果我这样做了,你可以通过以下方式优化算法:
int count = 0;
int a = 20, b = 10, c = 21;
sort(a, b, c); // Function that sorts the numbers, so that a is the smallest and c is the largest
count += a; // count = 10
c -= a; // a = 10, b = 20, c = 11
if(c < b) {
float diff = b - c; // diff = 9
float distribute = diff / 2; // distribute = 4.5
count += b - ceil(distribute); // count = 25
}
else count += b;
您必须将这个t乘以,然后对计数变量求和,从而导致t的复杂性。
问题内容: 我正在研究将RequestDTO发送到Web服务的类。我需要先验证请求,然后再发送。 可以从3个不同的地方发送请求,每个“ requesttype”都有不同的验证规则,例如request1必须具有名称和电话号码,request2必须具有地址,等等) 我有一个DTO,其中包含很长的字段列表(名称,地址,城市,电话号码等),无论请求是哪种类型,DTO都发送相同的消息。 我创建了3种不同的验
给定一个整数数组nums,查找具有最大和的相邻子数组(至少包含一个数字)并返回其和。 示例:
问题内容: 我有一个接收对象并根据其检测到的对象类型执行某些操作的方法: 如何降低环复杂性?我四处搜寻,但找不到任何有用的资讯。 问题答案: 您不能为此使用面向对象的方法吗?创建具有该方法的接口,然后创建实现所需行为的子类?然后调用将执行适当的行为?
帮助我减少这个程序的时间复杂性 输出:为每个测试用例输出这样的对的数量。 约束条件:T≤10;N≤100000;A[i]≤1000000 示例输入(明文链接)
以下代码是竞赛中问题陈述的解决方案。给出的时间限制为1s。该代码在5/7个测试用例中正常工作。对于其他情况,超过了时间限制。如何降低下面代码的时间复杂度? 编辑:问题陈述被定义为返回数字n的值或n/2、n/3、n/4之和,以最大值为准。例如,如果输入为24,则可以进一步减少或交换为12 8 6=26,12可以减少为6 4 3=13。8和6不应减少,因为这可能会降低值。最后的答案是13 8 6=27
我已经通过谷歌和堆栈溢出搜索,但我没有找到一个关于如何计算时间复杂度的清晰而直接的解释。 说代码像下面这样简单: 说一个像下面这样的循环: 这将只执行一次。 时间实际上被计算为而不是声明。