Помогите доработать алгоритм

127
19 июня 2022, 15:40

вот код:

не знаю, как доработать алгоритм

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    vector <int> pairs;
    int count = 0, n;
    cin >> n;
    for(int i = 0; i < n; i++){
        int temp;
        cin >> temp;
        pairs.push_back(temp);
    }
    sort(pairs.begin(), pairs.end());
    for(int cur = 0; cur < n; cur++){
        for(int sr = cur + 1; sr < n; sr++){
            if(max(pairs[cur], pairs[sr]) * 0.9 <= min(pairs[cur], pairs[sr])){
                count++;
            }
            else{
                break;
            }
        }
    }
    cout << count;
}
Answer 1

зачем сделали много лишних действий?

решение в лоб выглядит как-то так:

// отсортировать размеры по возрастанию
sort(pairs.begin(), pairs.end());
// рассматривать 
for (int first = 0; first < n - 1; first ++){
    for (int second = first + 1; second < n; second ++){
        if first < second * 0.9
            break;
        count++;
    }
}

по идее дальше можно делать оптимизации

Answer 2

Упорядочиваем массив по возрастанию.

[100, 102, 108, 109, 120, 125, 139]

Устанавливаем два указателя на его начало

 i j
[100, 102, 108, 109, 120, 125, 139]

теперь пока a[i] и a[j] находятся в пределах нужной разницы значений, прибавляем к результату количество пар, которые состовляет a[j] со всеми предыдущими значениями начиная с a[i]

 i j
[100, 102, 108, 109, 120, 125, 139]

плюс 0 пар

 i     j
[100, 102, 108, 109, 120, 125, 139]

плюс 1 пара (100, 102)

 i          j
[100, 102, 108, 109, 120, 125, 139]

плюс 2 пары (100, 108), (102, 108)

 i               j
[100, 102, 108, 109, 120, 125, 139]

плюс 3 пары (100, 109), (102, 109), (108, 109)

 i                    j
[100, 102, 108, 109, 120, 125, 139]

теперь разница между 100 и 120 слишком большая, сдвигаем i

      i               j
[100, 102, 108, 109, 120, 125, 139]

все еще большая

            i         j
[100, 102, 108, 109, 120, 125, 139]

еще плюс 2 пары (108, 120), (109, 120) и т.д.

Получается алгоритм, работающий за линейное время (вместе с сортировкой - n*log n)

И еще я бы посоветовал сравнивать не 0.9*x и y, а 9*x и 10*y, хотя в данной ситуации это роли не играет, при другом коэффициенте переход в вычисления с плавающей точкой может плохо сказаться на точности, благо диапазон значений ≤ 108 позволяет умножать на 10 без переполнения.

Answer 3

Сделал по совету @extrn Получилось что-то такое

sort(pairs.begin(), pairs.end());
    int i = 0;
    int j = 0;
    while(i < n and j < n){
        while(j < n){
            if(pairs[i] < 0.9 * pairs[j]){
                i++;
            }
            else{
                count += (j - i);
                j++;
            }
            
        }
    }

Но на 8 тесте валится из-за неправильного ответа Что здесь не так?

READ ALSO
Как распарсить в laravel request через foreach

Как распарсить в laravel request через foreach

уважаемые программисты)

185
Как создать Docker-окружение с Nginx + PHP 7.4 + Composer

Как создать Docker-окружение с Nginx + PHP 7.4 + Composer

Подскажите, что должно содержаться в файлах Dockerfile и docker-composeyml для того, чтобы поднять окружение с nginx, php 7

260
Валидация данных в форме

Валидация данных в форме

Создать форму для ввода электронного адреса в формате vasyapupkin@ukr

143