Задать вопрос
  • Как решить подобную задачу? ЕГЭ 2014 информатика

    @oxygen3
    Тоже писал эту задачу. Поддерживал минимум на префиксе. Стресс-тест дома программа прошла, правда в бланке из-за того, что писал на Pascal, а не на C++ написал for i := 1 to n по привычке, а надо было условие i < n, то есть до n-1;
    Итак, если мы находимся в элементе с номером i, то minpref - минимум на отрезке от 1 до i-6, который мы поддерживаем (в каждой итерации смотрим на элемент, который был 6 итераций назад и если a[i-6] < minpref то minpref = a[i-6]), и если a[i] * minpref < minout, то minout = a[i] * minpref. Как сделать это с памятью O(n) очевидно, у меня написан костыль, который работает с константной памятью(массив a), можно было использовать стандартную очередь, но за нее бы не поставили максимум баллов по критериям.
    Время работы - O(n).
    Кусок с считыванием от 0 до 5 можно запихать и в основной цикл, если предварительно всё заполнено +inf.

    Если не понятно, то могу какие-то моменты разъяснить.

    Собственно код:
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    double a[6];
    
    int main(void){
        int i,n;
        double minpref = 1000000, minout = 1000000, xcur, a[5];
    
        cin >> n;
        for (int i = 0; i <= 5; i++)
            cin >> a[i];
    
        for (int i = 6; i < n; i++){
            cin >> xcur;
            minpref = min(minpref, a[i % 6]);
            a[i % 6] = xcur;
            minout = min(minout, xcur * minpref);
        }
        cout << minout << "\n";
        return 0;
    }
    Ответ написан
  • Как решить подобную задачу? ЕГЭ 2014 информатика

    ManWithBear
    @ManWithBear
    Swift Adept, Prague
    Возможны проблемы с одинаковыми значениями данных на далеких позициях друг от друга (Не уверен).

    #include <iostream>
    using namespace std;
    struct elem {
        float data;
        int pos;
    };
    int main(int argc, const char * argv[]) {
        int N;
        cin >> N;
        if (N<7) {
            cout<<"Corrupted data";
        }
        elem minVal[13];
        for (int i=0; i<13; i++) {
            minVal[i] = {10001.0f+i,0};
        }
        float in;
        bool flag = true;
        for (int i=0; i<N; i++) {
            cin>>in;
            flag = true;
            for (int j=0; j<13 && flag; j++) {
                if (minVal[j].data>in) {
                    flag = false;
                    for (int i2=12; i2>j; i2--) {
                        minVal[i2] = minVal[i2-1];
                    }
                    minVal[j] = {in, i};
                }
            }
        }
        float result = INT_MAX;
        float mult = .0f;
        int delta = 0;
        for (int i=0; i<12; i++) {
            for (int j=i+1; j<13; j++) {
                mult = minVal[i].data*minVal[j].data;
                delta = abs(minVal[i].pos-minVal[j].pos);
                if (delta>=6 && result>mult) {
                    result = minVal[i].data*minVal[j].data;
                }
            }
        }
        cout<<result<<endl;
        return 0;
    }

    Если алгоритм не совсем понятен, вопросы в комменты :)
    Ответ написан
    4 комментария
  • Как решить подобную задачу? ЕГЭ 2014 информатика

    Идея решения такая, поддерживаем пару чисел дающих минимальное произведение (пусть они будут называться lhs и rhs) - будем обновлять эту пару при каждом новом прочитанном числе.

    Кроме пары дающей минимальное произведение храним так же 6 последних прочитанных чисел. Будем называть их a1, a2, a3, a4, a5, a6, где a1 - самое старое, а a6 - самое новое. При каждом новом прочитанном числе мы будем "сдвигать" эту последовательность.

    Плюс нужно хранить еще один элемент m - это минимальный из элементов, которые мы уже просмотрели, и который уже "выпал" из последовательности ai.

    Мясо начинается когда у нас прочитано 7 элементов, lhs - первый прочитанный элемент он же m, rhs - последний прочитанный элемент и он же a6. Читаем очередной элемент, назовем его cur, новую пару с минимальным произведением ищем среди этого множества:
    { (lhs, rhs), (lhs, cur), (a1, cur), (min, cur) }.

    Пусть найденная пара (x, y), тогда делаем следующее:

    lhs = x;
    rhs = y;
    m = min(m, a1);
    a1 = a2;
    a2 = a3;
    a3 = a4;
    a5 = a6;
    a6 = cur;

    Минимальное произведение в конце алгоритма должно быть равно lhs * rhs, если я нигде не облажался.
    Ответ написан