[英]C++ code - problems with сode execution time
有代碼。
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
他的任務是檢查是否有可能從給定的每個數小於相鄰兩個數的和。 (每個數字都小於兩個相鄰的數字)但是有一個問題 - 數字很多,代碼花費的時間太長。 請幫助我優化它,或者只是給一些建議。 數字不能是 null。時間限制:3.0 sn <= 500000
給你 n 個數字 a1, a2, ..., an。 是否可以將它們排列成一個圓圈,使每個數字都嚴格小於其鄰居的總和?
例如數組[1,4,5,6,7,8],左邊數組滿足條件,右邊數組不滿足,因為5≥4+1且8>1+6。 輸入數據第一行包含一個 integer n (3≤n≤105) - 數字的數量。
第二行包含 n 個整數 a1, a2, ..., an (1≤ai≤109) - 數字本身。 給定的數字不一定不同。
Output 如果沒有解決方案,在第一行打印“NO”。
如果存在,則在第一行打印“YES”。 之后,在第二行打印 n 個數字——數組中的元素按照它們在圓上的順序排列。 您打印的第一個和最后一個元素被認為是圓上的鄰居。 如果有多個解決方案,output 其中任何一個。 您可以打印一個以任何數字開頭的圓圈。
首先,我只簡要分析您的代碼的技術缺點 - 不會分析其含義。 之后,我將針對您定義的問題編寫解決方案。
您的代碼的性能問題是由於一些奇怪的決定:
(1) 通過值傳遞std::vector<int>
而不是通過引用SearchInt
function - 這意味着在每次 function 調用時分配和復制整個數組,
(2) 在 function main
中每個循環迭代調用SearchInt
兩次,而不是只調用一次,
(3) 在每次調用SearchInt
時對數組進行sort
- 它在循環之前已經排序。
老實說,您的代碼感覺非常耗時。 我只是想知道你是否打算讓它盡可能慢......
我不會根據問題描述來分析你的代碼的正確性。 老實說,即使在修復了技術缺陷之后,您的代碼在我看來也完全不是最優的並且非常難以理解 - 所以從頭開始解決問題對我來說更容易。
如果最大數小於第二個大數和第三個大數之和,則定義問題的答案為“是”,否則為“否”-這是因為所有數字都是正數(根據新發現的在 1 - 109 范圍內)問題描述)。 如果答案是肯定的,那么要制作一個滿足問題描述的圓圈,您只需要在輸入數字的排序序列中切換最大數字和下一個大數字的位置 - 僅此而已。
這是我的代碼(對於稍微寬松的輸入格式 - 我不檢查項目數量是否在單獨的行上並且所有項目都在同一行上 - 但所有正確的輸入都將被解析得很好):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.