Есть простая задача:
Задача Ваша программа должна определять, можно ли из двух списков целых чисел выбрать по одному числу так, чтобы в сумме они составили 10000.
Исходные данные Состоят из двух списков — одного, потом другого. Формат каждого из этих списков таков: в первой строчке записано количество Ni чисел в i-м списке, далее в Ni строчках по одному числу в строке записаны сами списки. Выполняются неравенства 1 ≤ Ni ≤ 50000, все элементы списков лежат в диапазоне от –32768 до 32767. Первый список упорядочен по возрастанию, второй — по убыванию.
Результат На выходе следует записать YES, если из списков можно выбрать по числу, которые в сумме дадут 10000 и NO в противном случае.
Я реализовал 2 решения:
№1
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n1;
cin >> n1;
int* nums1 = new int[n1];
for(int i=0; i<n1; i++){
cin>>nums1[i];
}
int n2;
cin >> n2;
set<int> nums2;
int t;
for(int i=0; i<n2; i++){
cin >> t;
nums2.insert(t);
}
for(int i=0; i<n1; i++){
if(nums2.find(10000-nums1[i]) != nums2.end()){
cout << "YES";
return 0;
}
}
cout << "NO";
return 0;
}
№2
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
unsigned int n1;
cin >> n1;
set<int> nums1;
int t;
for(int i=0; i<n1; i++){
cin >> t;
nums1.insert(t);
}
unsigned int n2;
cin >> n2;
bool res = false;
for(int i=0; i<n2; i++){
cin >> t;
if(nums1.find(10000 - t) != nums1.end())
res = true;
}
cout << ((res)?"YES":"NO");
return 0;
}
В итоге, после тестов, программа №1 использовала 1 468 КБ, а №2 2 020 КБ. В №1 я создавал массив и множество, когда в №2 только множество, то есть, по идее, памяти нужно меньше. Этого я не могу понять...
P.S. Только учусь, если не сложно, можете дать советы по оптимизации
Задачка то олимпиадная, скорость работы можно увеличить шикарно. Намёк первый: выбираем первое число из первого списка, ищем во втором место, где сумма nums1[0]+nums2[i]>10000 and nums1[0]+nums2[i+1]<10000
можно просто перебором начиная с нулевого индекса. Намёк второй: все числа из второго списка по индексам 0 .. i
будут всегда в сумме давать число больше 10000. Так-что работать можно начиная с индекса i+1. В первом списке элемент по нулевому индексу тоже уже не участвует, у него поиск делаем начиная с индекса 1. Дальше выполняем тоже-самое, но массивы меняем ролями. Берём num2[i+1]
и ищем в первом списке место j чтобы num1[j]+num2[i+1]<10000 and num1[j+1]+num2[i+1]>10000
. Поиск делаем линейно 1,2, и т.д. Успехов.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Скачал исходники программы на C++Довольно старая, написана, на сколько я понял, в Visual Studio Express 2008 (возможно ещё в более старшей версии)
Подскажите как открыть новое окно поверх основного ? Есть следующий код написанный на C: