Ответы пользователя по тегу Массивы
  • Сколько элементов массива больше своих соседей (предыдущего и следующего элементов)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Чтобы пропустить первый и последние элементы просто измените границы цикла:
    for (int i = 1; i < 24; i++)

    Если вы хотите эти элементы считать, если они больше единственного их соседа, то воспользуйтесь ленивым вычислением логических формул (при вычислении A || B, если A == true, то B вообще вычисляться не будет):
    for (int i = 0; i < 25; i++)
      {
        if ((i +1 == n || ARR[i] > ARR[i + 1]) && 
             (i == 0 || ARR[i] > ARR[i - 1]))
          count++;
      }
    Ответ написан
    1 комментарий
  • Как складывать элементы двумерного массива с++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам нужен цикл по строкам. Внутри считайте сумму каждой строки и выводите.
    Чтобы найти сумму одной строки вам нужен еще один цикл: Заводите переменную, равную 0, перед цикорм. В цикле прибавляете элементы строки к ней. Потом выводите.

    Таким образом, у вас будет 2 вложенных цикла.
    Ответ написан
    2 комментария
  • Си: Как осуществить поиск ближайшего в массиве?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Бинарный поиск

    Только надо чуть чуть изменить. В конце вы останетесь на каком-то элементе ближайшем к искомуму слева или справа.
    Так что провертьте left и 2 соседних элемента на ближайшесть.
    Ответ написан
    Комментировать
  • Как задать матрицу X[5][7] на С?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Два цикла вложенных в друг друга. Внешний по строкам, 5 итераций. Вложенный по столбцам, 7 итераций. Внутри считывание одного числа с клавиатуры, но читаете не в какую-то переменную а в x[i][j].
    Ответ написан
    Комментировать
  • Как ускорить программу?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Надо использовать более умный и быстрый алгоритм. Вы после каждой помены за O(n) проверяете, что массив отсортирован. когда как можно делать это за O(1) - ведь массив меняется всего в двух местах.

    Для понимания алгоритма, сначала сделаем немного другую версию за O(n), а потом соптимизируем до константы.
    Вы вместо сравнения с сортированным массивом пройдитесь по массиву и смотрите, что для всех соседних элементов следующий более или равен предыдущему.
    Следующий шаг - заведите массив bool на n-1 элемент и храните в нем пометки, что в данной позиции массив отсортирован. При помене местами двух элементов надо пересчитать 4 позиции в этом массиве. Потом пройдитесь по массиву и проверьте, что там все элементы true. Пока все еще работает за линию и еще хранит лишний массив.
    А теперь последний шаг - можно не проходиться по массиву bool каждый раз, если поддерживать счетчик, сколько там истинных элементов. После ввода массива list надо будет заполнить массив bool-ов и подсчитать, сколько там true. При перестановке a и b у вас максимум 4 элемента в массиве bool могут поменяться. Вот при этих изменениях вы счетчик пересчитывайте. Просто тупо при каждой записи в этот массив вычтите 1 из счетчика, если текущее там значение true и прибавьте 1, если новое значение true.
    Ответ написан
    Комментировать
  • Как получить всевозможные комбинации массива PHP?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Подсчитайте руками, сколько комбинаций для массива из 1,2,3,4 элементов? ответ будет 1,3,7,15 - степени двойки минус один. Подумайте, откуда это берется? Каждый элемент может или быть в ответе, или нет. 2 варианта. Премножаем все, получаем степень двойки. Но это учитывает варинат пустого ответа, поэтому один надо вычесть.

    Тут есть 2 подхода - рекурсивная функция перебора, которая или берет или пропускает текущий элемент. В конце, если хоть один элемент был взят - выводит текущий массив.

    Второй подход - перебирать битовую маску. Каждое число от 1 до 2^n будет в двоичной системе числения представлять какой-то вариант выбора разрядов. Поэтому можно прогнать цикл от 1 до 2^n, потом посмотреть на биты этого числа и брать соотвествтующие числа из массива.
    Ответ написан
    Комментировать
  • Как перенести строку в двумерном массиве, если количество элементов больше определенного количества?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Тут не важно, что массив двумерный. Фактически, вам надо вывести один массив символов с переносами. Только надо решить эту задачу отдельно для каждой строки двумерного массива.

    Самое простое решение - в цикле вывода символов выводить '\n', если текущий символ 20-ый, 40-ой и т.д. Например, можно проверять (i+1) % 20 == 0.
    Ответ написан
    Комментировать
  • Не понимаю в чём ошибка, можете помочь?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    У вас $rank равен 8, когда как допустимые значения 0..7. И вы обращаетесь по недопустимуому индексу в массиве, в котором 8 элементов.
    Ответ написан
    Комментировать
  • Как решить проблему с вводом двумерного массива?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Как вам уже сказали, вы не выделяете массив нужного размера. Можно вместо int a[1][1] делать int a[100][100], например, если вам известно, что массив не будет больше 100 строк и столбцов. Но, по хорошему, это надо обработать и, если пользователь ввел row == 101, то надо завершиться, сообщив пользователю о слишком большой размерности.
    Ответ написан
    Комментировать
  • Расположите строки массива в порядке возрастания количества одинаковых элементов в каждой строке?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Это тривиальное задание. Что вы попытались сделать сами? Смогли массив прочитать? Можете подсчитать, сколько одинаковых элементов в строке? Алгоритм сортировки вызвать можете?
    Ответ написан
  • Как переделать функцию сортировки вставками по убыванию?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Поменяйте < на > там, где у вас сравниваются элементы. Подсказка: у вас массив передан двумя int указателями. Т.е. сами элементы - это там где вы разименовываете какие-то указатели (это операция *что-то).
    Ответ написан
    Комментировать
  • Как решить эту задачу, используя массив char'ов?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну... читайте по одному символу. Можно считать, допустим, начала слов. Что такое начало слова? Это символ-буква, перед которым стоит не буква. Все, что вам надо хранить - это был ли буквой предыдущий символ. Если предыдущий не был, а текущий - является, то прибавляете 1 к ответу. Еще надо аккуратно рассмотреть случай слова в самом начале (т.е. фактически прибавляете 1 если текущий - буква и позиция == 0 или предыдущий символ - не буква).
    Ответ написан
    Комментировать
  • Как определить все способы выплаты суммы n с помощью монет достоинством в 1, 5, 10, 15, 20, 50 копеек?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это задача о рюкзаке.

    Решение через динамическое программирование:
    int Count(vector<int> coins, int n) {
      vector<int> cnt(n+1, 0);
      cnt[0] = 1;
      for (int i = 0; i < n; ++i) {
        for (int coin : coins) {
          if (i+coin <= n) cnt[i+coin] += cnt[i];
        }
      }
      return cnt[n];
    }
    Ответ написан
    9 комментариев
  • C#. Есть два массива, как сделать проверку данных на совпадение?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Вариант тупой - для каждого элемента первого массива пройтись циклом по второму массиву и сравнить.

    Вариант по-умнее: Отсортировать оба массива, пройтись по ним двумя указателями параллельно (Если текущие элементы совпали - нашли совпадение и двигаем оба указателья, иначе двигаем указатиль на меньший элемент. Если один из массивов кончился - все).

    Лучший вариант: Пройтись по меньшему массиву и сложить его элементы в HashSet<> (через Add()). Потом пройтись по второму массиву и каждый элемент проверить через метод Contains() у сета.
    Ответ написан
    2 комментария
  • Как решить данную задачу по курсовой на языке С++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам ДАНА матрица. Значит в программе надо
    1) прочитать числа N и M (заведите 2 переменные и прочитайте их, через cin)
    2) Завести N*M матрицу. В C++ стандартом для массивов является класс vector. Двумерный массив - это вектор векторов.
    vector<vector<int>> a(n);
    Это создаст вектор из n векторов, но они все будут пустые. Надо во время считывания ( у вас будет 2 вложенных цикла) перед считыванием i-ой строки i-ый вектор отресайзить вызвав a[i].resize(m). И далее можно будет читать a[i][j]
    3) Теперь, собственно, алгоритм. Найдите наибольший элемент. Для этого заведите 3 переменные - текущий максимум (можно инициализировать a[0][0]) и его координаты mx и my (инициализируйте нулями). Пройдитесь по матрице двумя вложенными циклами и, если текущий элемент больше максимума - перезапишите максимум и запомните текущие переменные циклов в mx и my.
    4) Теперь поменяйте местами 0-ую строку со строкой в которой максимум. Для этого одним циклом пройдитесь по столбцам (от 0 до M-1) и поменяйте местами a[0][j] и a[mx][j].
    5) Теперь то же самое, но по столбцам. Цикл от 0 до N-1 и меняйте элементы a[i][0] и a[i][my].
    6) В конце выведите матрицу двумя вложенными циклами.

    Для смены двух значений нужна временная перменная, например tmp.
    Ответ написан
    1 комментарий
  • Какие есть варианты получить все свойства многомерного массива?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    У вас, фактически, задано дерево. Каждая вершина - это элемент на каком-то уровне в массиве. Его свойство SUB - это дети дерева.

    Вам надо получить список всех вершин, т.е. обойти дерево. Тут есть 2 стандартных решения - обход в ширину и обход в глубину. В глубину - это рекурсивная функция. В ширину, это будет итеративное решение, но нужна очередь.

    Рекурсивное решение пишется легче всего, как мне кажется.
    Ответ написан
    Комментировать
  • Комбинаторика в Java Script, как добавить точку во всех возможных комбинациях массива?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Делайте рекурсивную функцию, которая решает вашу задачу. Если символ на входе 1 - просто его и возвращает. Если входных символов несколько - то откусывает последний символ и вызывается рекурсивно, потом к возвращенному массиву к каждому элементу дописывает последний символ и точку-последний символ (новый массив с удвоенным количеством элементов).

    Так для 3 символов "abc" будет вызвана функция для "ab", которая вернет [ab, a.b], дописав "c" и ".c" к каждому элементу мы получим [abc, ab.c, a.bc, a.b.c].
    Ответ написан
  • Как переставить элементы массива из конца в начало?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Большинство решений, уже предложенных тут, работают за квадрат и уже для n=10000 amount=5000 будут работать заметно долго. Конечно, вряд ли такое большое количество данных будет на клиенте, но даже при n=100, если функция выполняется часто, зачем ее делать в ~50 раз медленнее?

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

    Если хотите без splice(), то надо завести новый массив и потом скопировать в него элементы n-amount..n-1 в начало одним циклом, потом вторым циклом скопировать дальше элементы 0..n-amount-1.

    Зафиксированный вами интерфейс предполагает использование нового массива для результатов каждый раз. Но можно было бы сделать без использования много дополнительной памяти, тусуя сам массив на месте, если допустить изменение интерфейса.

    Правда, splice уже нельзя было бы использовать. Еще надо было бы знать теорию перестановок немного. Короче, вот решение, которое работает за линию и перемешивает массив на месте:

    function gcd(a,b) {
     if (a>b) return gcd(b,a);
     return a == 0? b : gcd(b%a, a);
    }
    
    function next(i, k) {
      return i >= k ? i-k : i+n-k
    }
    
    function moveToStartInPlace(arr, k) {
      n = arr.length;
      num_cycles = gcd(k,n)
      for (i=0; i < num_cycles; ++i) {
       saved_value = arr[i];
       j = i;
       nxt = next(j, k);
       while (nxt != i) { 
         arr[j] = arr[nxt];
         j = nxt;
         nxt = next(j, k);
       }
       arr[j] = saved_value;
      }
    }


    Возможно, это не лучшая реализация - я не специалист по JS. Суть этого решения в том, что мы берем какой-то элемент и ставим на его место нужный элемент после перестановки. На освободившееся место ставим следующий элемент и так далее, пока не вернемся к начальной позиции (а мы всегда вернемся, потому что перестановки только так и работают).

    Функция next() возвращает, какой элемент должен встать на место i-ого в итоговом массиве.
    Если немного подумать, то станет понятно, что в перестановке ровно gcd(n,k) циклов, потому что в ней все прыжки делаются на +(n-k) или -k. Т,е. фактически делаются только прыжки -k(mod n). А это уже известный факт: если прыгать по массиву на +k, оборачиваясь из конца в начало, то мы вернемся в ту же точку, с которой начали и всего таких циклов будет gcd(n,k).
    Ответ написан
    Комментировать
  • Как проверить массив на возрастание?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ваше решение не работает на примере 3,4,1,2. Тут нельзя удалить одно число, но ваша программа вернет true.

    В случае, если вы нашли один участок с убывающими соседними числами, надо проверить, что будет если удалить первое или второе число.
    Ответ написан
    Комментировать