Помогите разобраться с памятью

195
01 августа 2018, 05:30

Есть простая задача:

Задача Ваша программа должна определять, можно ли из двух списков целых чисел выбрать по одному числу так, чтобы в сумме они составили 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. Только учусь, если не сложно, можете дать советы по оптимизации

Answer 1

Задачка то олимпиадная, скорость работы можно увеличить шикарно. Намёк первый: выбираем первое число из первого списка, ищем во втором место, где сумма 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, и т.д. Успехов.

READ ALSO
Не работает break point и выдает -nan(ind)

Не работает break point и выдает -nan(ind)

Решаю задачу по программированию (Работа с файлами)

221
Где взять LNK1104 не удается открыть файл &ldquo;icmp.lib&rdquo;?

Где взять LNK1104 не удается открыть файл “icmp.lib”?

Скачал исходники программы на C++Довольно старая, написана, на сколько я понял, в Visual Studio Express 2008 (возможно ещё в более старшей версии)

196
Отрисовка нового окна в qml

Отрисовка нового окна в qml

Подскажите как открыть новое окно поверх основного ? Есть следующий код написанный на C:

174
Вывод в поток массива вектора пар

Вывод в поток массива вектора пар

При попытке вывода в консоль выводит только адрес в памяти:

178