LINUX.ORG.RU

Решение задачи посредством two pointer technique

 ,


0

1

последняя задача из списка.

Массив данных - N чисел. Найти в нем такую последовательность K чисел, чтобы сумма разниц каждых двух чисел в этой последовательности, деленная на количество этих этих пар чисел, была минимальной.

Решение на с++. Не могу составить полную картину/сложить воедино то, что он делает.

#include <bits/stdc++.h>
using namespace std;
 
#define lli long long
#define MAX 1000006
 
lli A[MAX],C[MAX];
 
int main()
{
    int l = 1, r = 2, st,en,n;
    
    lli sum,ans;
 
    cin >> n >> k;
    
    for ( int i = 1; i <= n; i++ ) cin >> A[i];
 
    sort(A+1, A+n+1);
 
    cum[0] = 0;
    for ( int i = 1; i <= n; i++ ) cum[i] = cum[i-1] + A[i];
    
    while ( r <= k ) {
       sum += (A[r]*(r-l) - (cum[r-1] - cum[l-1]));
       r++;
    }
 
    st = 1, en = k, ans = sum;
 
    while ( r <= n ) {
       sum -= (cum[r-1] - cum[l] - A[l]*(r-l-1));
       l++;
       sum += (A[r]*(r-l) - (cum[r-1] - cum[l-1]));
        
       if ( ans > sum ) {
          ans = sum;
          st = l;
          en = r;
       }
       r++;
    }
    return 0;
}

1) Объявляет список C и не использует. Он для чего?
2) cum - некая последовательность чисел, в которой каждое последующее число - это сумма всех предыдущих + текущее значение, взятое из отсортированного списка A с индексом i. Дальше не ясно.

В цикле while каждый раз увеличивается увеличивается список sum на элемент, получаемый путем умножения элемента из А с индексом r на некую разницу индексов и вычитания элементов последовательности cum с прочими индексами. Как это все сопоставляется друг с другом? Общая цель понятна, а по отдельности нет.
3) как результат выводитсся? Где cout или прочее прохожее на stdout



Последнее исправление: hibiscusM (всего исправлений: 4)
  1. Объявляет список C и не использует. Он для чего?

Следствие копипасты. Наверное, должно быть cum.

cum[r-1] - cum[l-1]

Это сумма элементов A[l:r) или вроде того (границы могут быть другого типа).

(A[r]*(r-l) - (cum[r-1] - cum[l-1]))

А это, видимо: (A[r] - A[l]) + (A[r] - A[l + 1]) + ... (A[r] - A[r - 1]).

  1. как результат выводитсся? Где cout или прочее прохожее на stdout

Никак, код не полон.

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Подскажите, пожалуйста 1)sum и ans это что за тип данных?
Слабовато разбираюсь в языках с/с++. Но в целом код на с++ интуитивно понятен.
2)Вроде бы должна быть инициализация/ initialization для sum/ans, а ее здесь нет. Это небрежность при написании кода или что?

hibiscusM
() автор топика
Ответ на: комментарий от hibiscusM

1)sum и ans это что за тип данных?

#define lli long long

Это long long – обычно 64 битное целое.

Слабовато разбираюсь в языках с/с++.

Это практически C, от C++ только cin.

2)Вроде бы должна быть инициализация/ initialization для sum/ans, а ее здесь нет. Это небрежность при написании кода или что?

ans ниже присваивается, а sum не инициализируется. k вообще не объявлена. Код скорее всего не запускали, а просто перевели с другого языка.

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Спасибо, понятно.

Это практически C, от C++ только cin

возможно, от С++ еще сортировка

Standard Template Library (STL) , С++ , std::sort

Sort elements in range. Sorts the elements in the range [first,last) into ascending order.

The elements are compared using operator< for the first version, and comp for the second.

stdlib.h , С, qsort

И сравнение двух функций

C qsort() vs C++ sort()

qsort function uses QuickSort algorithm to sort the given array
C++ sort function uses introsort which is a hybrid algorithm

3. Running time: STL’s sort ran faster than C’s qsort, because C++’s templates generate optimized code for a particular data type and a particular comparison function.

STL’s sort runs 20% to 50% faster than the hand-coded quicksort and 250% to 1000% faster than the C qsort library function. C might be the fastest language but qsort is very slow.

When we tried to sort one million integers on C++14, Time taken by C qsort() was 0.247883 sec and time taken by C++ sort() was only 0.086125 sec

В общем sort() у С++ намного быстрее.

hibiscusM
() автор топика
Ответ на: комментарий от hibiscusM

не верь таким статьям, std::sort конечно побыстрее, чем qsort, но никогда и близко не было 1000%. Хотя процентов 20-50% может и будет сейчас(именно в сортировке), нужно сравнивать, когда я последний раз бенчил, у меня было что-то типа такого: 7 секунд std::sort, 11 секунд qsort...

В std::sort не описан алгоритм сортировки, только сложность.

То что некоторые стандартные библиотеки используют introsort(например библиотека gnu), это лишь случайность. Я читаю багзиллу libc++ и запомнил это: https://bugs.llvm.org/show_bug.cgi?id=20837 , так как баг до сих пор не закрыт, то делаем вывод, что libc++ использует quick sort.

Я видел стандартную библиотеку, которая использовала алгоритм Timsort для std::sort...

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Я видел стандартную библиотеку, которая использовала алгоритм Timsort для std::sort...

Во идиотизм, его же специально для питона изобрели, где сравнение (вызов питоновского кода) крайне дороже, чем свап (свапнуть два указателя, лол).

В других условиях оно сливает где-то раз в 10 же.

anonymous
()
Ответ на: комментарий от anonymous

Да, анон ты прав, это на гитхабе кто-то фанился и делал свою стандартную библиотеку.

Вот ещё что хотел дополнить:

qsort function uses QuickSort algorithm to sort the given array

Опять мимо, хоть и написано qsort, стандарт не запрещает использовать любой алгоритм сортировки с подходящей сложностью. В частности glibc использует тот же introsort.

Вот сравнение стандартных библиотек С, слегка устаревшее но в целом норм: http://www.etalabs.net/compare_libcs.html

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Ну да, статья на geeksforgeeks не корректна в этих вопросах. Действительно несколько источников указывают, что в glibc используется introsort, а в musl - smoothsort, если верить eta labs.

hibiscusM
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.