1. C++ / Говнокод #9492

    +141

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n, m, c, b, f = 0;
        cin >> n >> m;
        int A[n][m];
        for(int i = 0; i < n; i++ )
        {
            for(int j = 0; j < m; j++)
            {
                cin >> A[i][j];
            }
        }
    
            for(int i = 0; i < n; i++ )
            {
                b = A[i][0];
                for(int j = 0; j < m; j++)
                {
                c = A[0][j];
                for(int a = 0; a < n; a++)
                 {
    
                     if(c < A[0][a])
                     {
                         c = A[0][a];
                     }
                 }
                 for(int k = 0; k < m; k++)
                 {
    
                     if(b > A[k][0])
                     {
                        b = A[k][0];
                     }
                 }
    
    
                 if(b == c)
                 {
                     f++;
                 }
                }
            }
                cout << f;
                return 0;
    }

    Задана матрица K, содержащая n строк и m столбцов. Седловой точкой этой матрицы назовем элемент, который одновременно является минимумом в своей строке и максимумом в своем столбце.

    Найдите количество седловых точек заданной матрицы.
    Вроде всё правильно, а выдаёт, что есть необработаное исключение.Что не так?

    Запостил: alexsid13, 20 Февраля 2012

    Комментарии (20) RSS

    • Думаю тебе стоит пойти на xakep.ru с этими вопросами.
      Ответить
    • Жаль, что компилятор не предупреждает, когда линейные по природе алгоритмы превращают в говно кубической сложности.
      Ответить
      • Вспомнилось про динамические задачи с кешированием результатов.
        Ответить
      • автор - основоположник кубизма в программировании
        Ответить
      • ну я тут вижу O(n^2) действий при памяти O(1), либо O(n) действий при памяти O(n), причем константы и (не)качество исходных данных во втором случае могут запросто перевесить решение в лоб
        Ответить
        • квадратик растёт так быстро, что я всегда предпочту второй вариант (если у нас в память поместилась большая матрица, ещё уж одна строка и один столбец и подавно поместятся).
          Ответить
          • почему одна строка и один столбец?
            для матрицы
            ( 1, 1, 1,
              1, 1, 1,
              1, 1, 1 )
            судя по педивикии будет 9 седловых точек
            Ответить
          • Эта задача решается за O(n) только если 'n' - общее количество элементов матрицы, т.е. сама по себе величина квадратичная (т.е. это 'm*n' в исходной постановке). Т.е разглагольствовать в данном случвае об некоем "линейном" алгоритме O(n) - это не более чем дешевая попытка спрятать существенную квадратичность "внутри" размерности величины 'n'.

            Если бы 'n' являлось мерой стороны матрицы (т.е. величиной той же размерности, что и 'm' и 'n' в исходной постановке), то решить задачу за O(n) было бы в принципе невозможно. Если 'N' - сторона матрицы, то O(N^2) является нижней оценкой сложности алгоритма. Более эффективного алгортма нет и быть не может по соврешенно очевидным причинам.

            Отсюда возникает вопрос: о какой дополнительной строке и столбце вы ведете речь? Для алгоритма O(n) в данном случае дополнительная память в объеме O(n) - это еще одна (или несколько) таких же матриц, а не какие-то жалкие "строка и столбец".

            Если вам известен некий алгоритм, который решает задачу за O(n) с дополниельной пямятью O(n), и при этом размерность величины 'n' - это строна матрицы, то давайте этот алгоритм в студию - это будет большой вклад в науку.
            Ответить
            • Да, я был неправ: если все элементы матрицы могут быть седловыми точками, то минимально получается O(n^2). Линейность возможна только в том случае, если допускаются лишь строгие неравенства (как раз в этом случае и нужны лишь значения индекса минимума/максимума для каждой строки и каждого столбца, отсюда и один столбец/одна строка). Алгоритм в топе (который использует именно строгие неравенства) по сути можно выразить так, чтобы он требовал O(N) операций и O(N) памяти, где N = n + m, а не O(N^3) (в предположении, что n и m - величины одного порядка)
              Ответить
              • Я не понимаю.

                Для меня очевидно следующее: если у нас есть матрица 'n x n', и природа самой задачи требует доступа к каждому элементу такой матрицы, то любой алгоритм решения этой задачи будет как минимум O(n^2). Это, фактически, аксиома. Как ни верти, быстрее чем за O(n^2) не сделаешь. А строгие там неравенства или нестрогие, все элементы седловые или не все - роли никакой не играет.

                Надеяться на улучшение этой оценки можно только в том случае, когда у нас есть какая-то дополнительная информация о матрице, намного более сильная, чем "строгие неравенства". (Например, если матрица заранее как-то хитро упорядочена.)

                Без этого - как минимум O(n^2), как ни верти.
                Ответить
                • И опять вы правы... Для поиска поиска минимумов и максимумов потребуется O(n*m) операций, получаем квадрат в любом случае. Беру свои слова обратно. Видимо, голова не тем сегодня забита. Спасибо за просветление :)
                  Ответить
                  • Ну понятно, что точки перебрать - это квадрат полюбэ.
                    Но в том, что тут мы видим куб, потому что ля каждой точки перебором проверяется, максимальна ли она.
                    Ответить
                    • почему нельзя совместить "квадратный" перебор и поиск максимума?
                      Ответить
                      • Можно, но автор кода не смог, получил куб.
                        Ответить
                    • Да, справедливое утверждение звучит так:
                      Жаль, что компилятор не предупреждает, когда квадратичные по природе алгоритмы превращают в говно кубической сложности.
                      Ответить
    • Перепутаны переделы 'm' и 'n' в циклах по 'a' и 'k'.

      Это то, что сразу видно. А что там, собственно, понаписано - не разбирал.

      Понятно, конечно, что пытаться независимо искать минимум в строке и максимум в столбце и затем проверять, совпали ли они - занятие совершенно бессмысленное. А также бесполезное в ситуациях, когда экстремальные элементы определяются неоднозначно.
      Ответить

    Добавить комментарий