Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
 Аватар для maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457

Алгоритм выбора попарно разных значений с n строк

08.10.2015, 19:07. Показов 749. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть n строк, нужно взять с каждой такое число , чтобы между всех выбранных не было одинаковых, или же вывести, что это невозможно.
Ограничение по времени - пол секунды, а по n : n<=300.
300 факториал явно не пройдет, максимум n^3.
Подскажите, как это сделать
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.10.2015, 19:07
Ответы с готовыми решениями:

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

Сумма значений ячеек БД из разных строк
Доброе время суток. Подскажите как сделать такую вот вещь: в Delphi с помощью DBGrid рассчитать значения ячеек из базы данных Access....

Выбор двух значений из разных строк в одном запросе
Помогите, решить проблему: есть таблица +----------+-------+------+-------+ | id | title | value | class | ...

13
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
09.10.2015, 00:30
а сколько чисел в строках?
0
 Аватар для maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
09.10.2015, 01:03  [ТС]
максимум 300 тоже
0
Регистрация: 23.10.2013
Сообщений: 5,076
Записей в блоге: 8
09.10.2015, 09:26
Есть такой вариант. Провести сортировку и выбросить все одинаковые числа. Если какая либо строка "исчезнет", то эта задача неразрешима. Сортировка естественно с заменой на 0 или иное число.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
09.10.2015, 10:36
Цитата Сообщение от maxm Посмотреть сообщение
300 факториал явно не пройдет
Каждое число будет текущим не более одного раза. Поэтому сложность О(n2). Если вместо хэш-таблицы использовать обычный массив, то сложность будет О(n3).
У меня даже 3000 укладывается в полсекунды.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int[] Solve(int[][] aaa)
{
    int[] res = new int[aaa.Length];
    HashSet<int> set = new HashSet<int>();
    for(int i = 0;;)
    {
        int j = res[i];
        if(j >= aaa[i].Length)
        {
            // переходим к следующему брату родителя
            if(--i < 0) return null; // решения нет
            res[i]++;
            continue;
        }
 
        int a = aaa[i][j];
        if(set.Contains(a))
        {
            // переходим к следующему брату текущего узла
            res[i]++; 
            continue;       
        }
        
        set.Add(a);
        // переходим к первому сыну текущего узла
        if(++i >= res.Length)
        {
            // решение найдено
            for(int k = 0; k < res.Length; k++)
                res[k] = aaa[k][res[k]]; // заменяем индексы на числа
            return res; 
        }
        res[i] = 0; 
    }
}
0
 Аватар для maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
09.10.2015, 11:58  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
int[] Solve(int[][] aaa)
Можете сказать, что это за синтаксис и где почитать об этом? с сетом я знаком, это не знаю что такое
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
09.10.2015, 12:49
Shamil1, предлагаю запустить на тесте: в 1 строке числа 1...300, во 2 1...299, в 3 1..298 и т.д. в последней(300-ой) строке одно число - 1. Есть предположение, что твой код работает за экспоненту а не за полином. И еще, насколько я понял твой код, в нем есть бага(вернее не бага, а недостающая строка), из сета надо иногда удлаять числа, к примеру, на тесте выше этот код кажется скажет, что решения нет. Но если даже багу исправить то этот код будет искать ответ очень долго.
1
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
09.10.2015, 14:48
Цитата Сообщение от maxm Посмотреть сообщение
Можете сказать, что это за синтаксис и где почитать об этом?
int[] - это массив целых чисел
int[][] - это массив ссылок на массивы целых чисел
(каждая строка во входных данных - это массив целых чисел)

Добавлено через 1 минуту
Цитата Сообщение от SlavaSSU Посмотреть сообщение
И еще, насколько я понял твой код, в нем есть бага(вернее не бага, а недостающая строка), из сета надо иногда удлаять числа,
Да, есть такая бага. Торопился и в какой-то момент забыл удалять.

Добавлено через 24 минуты
Цитата Сообщение от SlavaSSU Посмотреть сообщение
Есть предположение, что твой код работает за экспоненту а не за полином.
Тоже верно. Полином получался из-за предыдущей ошибки.
0
 Аватар для maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
09.10.2015, 14:53  [ТС]
Я о скобках после int в первой строке, где int функция ч параметром Solve, где Solve двумерн. массив
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
09.10.2015, 14:54
в скобках в первой строке аргументы функции
0
 Аватар для maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
09.10.2015, 20:44  [ТС]
int [] в первой строке
какие там аргументы ?
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
10.10.2015, 00:33
это тип возвращаемого функцией значения
но, как заметил выше SlavaSSU, данная реализация работает за экспоненциальное время, так что Вам не подойдёт (и там нужно добавить перед 12 строкой удаление из set)
0
1968 / 824 / 115
Регистрация: 01.10.2012
Сообщений: 4,856
Записей в блоге: 2
10.10.2015, 07:35
Что-то подобное в этом году было (там еще туча битовых масок). И опять у меня нет времени продумать до конца Если без перебора, то смысл такой

Мы должны взять число из какой-то очередной строки. На этот момент какое-то число чисел уже задействовано, и нам совершенно все равно из каких пройденных строк, дальнейший "путь" от этого не зависит. Вместо того чтобы хранить все комбинации использованных для каждой строки - нужно строить для нее дерево, но вот дальше не соображу. В общем, как говорят буржуины
Hope it helps
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
11.10.2015, 18:56
Вот решение, работающее, насколько я понимаю, за O(n3) в худшем случае.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
public class Problem
{
    int[][] rows; // массивы индексов чисел, которые может содержать строка 
    List<int> numbers; // значения чисел (по индексу)
    int?[] matchings; // индекс строки, для которой выбрано число (по инедксу)
    
    
    public Problem(int[][] aaa)
    {
        // 1. готовим массив строк и массив чисел
        rows = new int[aaa.Length][];
        numbers = new List<int>();
        Dictionary<int,int> numberIndexes = new Dictionary<int,int>();
        for(int i = 0; i < aaa.Length; i++)
        {
            int[] aa = aaa[i];
            rows[i] = new int[aa.Length]; 
            for(int j = 0; j < aa.Length; j++)
            {
                int a = aa[j];
                int index;
                if(!numberIndexes.TryGetValue(a, out index))
                {
                    index = numbers.Count;
                    numbers.Add(a);
                    numberIndexes.Add(a, index);
                }
                rows[i][j] = index;
            }
        }
    }
    
    public int[] Solve()
    {
        if(numbers.Count < rows.Length)
            return null;
    
        // 2. Сортируем строки в порядке возрастания количества возможных чисел
        int[] rowIndexes = new int[rows.Length];
        for(int i = 0; i < rowIndexes.Length; i++)
            rowIndexes[i] = i;
        Array.Sort(rows, rowIndexes, new ByLengthComparer());   
        
        // 3. Ищем соответсвия для строк методом "первое свободное число"
        matchings = new int?[numbers.Count];
        bool[] hasMatching = new bool[rows.Length];
        for(int i = 0; i < rows.Length; i++)
            for(int j = 0; j < rows[i].Length; j++)
                if(!matchings[rows[i][j]].HasValue)
                {
                    matchings[rows[i][j]] = i;
                    hasMatching[i] = true;
                    break;
                }
    
        // 4. Для оставшихся строк ищем соответсвия поиском в глубину
        visitedRows = new bool[rows.Length];
        for(int i = 0; i < rows.Length; i++)
        {
            if(hasMatching[i])
                continue;
            for(int k = 0; k < visitedRows.Length; k++)
                visitedRows[k] = false;
            if(!Dfs(i))
                return null;
        }
        
        // 5. восстанавливаем исходные номера строк и числа для ответа
        int[] result = new int[rows.Length];
        for(int i = 0; i < matchings.Length; i++)
            if(matchings[i].HasValue)
                result[rowIndexes[matchings[i].Value]] = numbers[i];
        return result;
    }
    
    bool[] visitedRows; 
    bool Dfs(int i)
    {
        if(visitedRows[i]) return false;
        visitedRows[i] = true;
        for(int j = 0; j < rows[i].Length; j++)
        {
            int to = rows[i][j];
            if(!matchings[to].HasValue || Dfs(matchings[to].Value))
            {
                matchings[to] = i;
                return true;
            }
        }
        return false;
    }
    
    private class ByLengthComparer: IComparer<int[]>
    {
        public int Compare(int[] a, int[] b)
        {
            return a.Length.CompareTo(b.Length);
        }
    }
}
Массив numbers содержит все встречающиеся числа.
Каждый элемент массива строк rows содержит числа (их индексы в массиве numbers), которые можно выбрать для данной строки.

Если чисел меньше чем строк, то решения нет.

Сортируем стоки в порядке возрастания количества чисел, которые можно выбрать. Чтобы сначала выбирать числа для тех строк, для которых меньше вариантов. Это позволит увеличить эффективность жадного алгоритма на следующем шаге.
В массиве rowIndexes сохраняем исходные номера строк (для восстановления ответа).

Для каждой строки выбираем число наивным (жадным) алгоритмом.

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

Добавлено через 2 часа 1 минуту
Вчера несколько часов писал программу (правда параллельно смотрел телевизор, что мешало сосредоточиться). И в какой-то момент понял (почти одновременно) несколько вещей:
1. Та часть программы, которую я пишу - это вариация обхода в ширину
2. Вместо возни с состояниями проще использовать рекурсивный обход в глубину
3. Решаемая задача - это поиск максимального паросочетания
4. А то, что я пишу - это вариация алгоритма Куна
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.10.2015, 18:56
Помогаю со студенческими работами здесь

Найти количество строк в максимальном множестве попарно непохожих строк заданной матрицы.
Две строки матрицы назовем похожими, если совпадают множества чисел, встречающихся в этих строках. Найти количество строк в максимальном...

Найти количество строк в максимальном множества попарно непохожих строк заданной матрицы
Две строки матрицы назовем похожими, если совпадают множества чисел, встречающихся в этих строках. Найти количество строк в максимальном...

Найти количество строк в максимальном множестве попарно непохожих строк заданной матрицы
Мир всем, помогите понять суть задания: &quot;Две строки матрицы назовем похожими, если совпадают множества чисел встречающихся в этих...

Как получить номера строк для пар значений из разных столбцов и посчитать их количество?
Добрый день уважаемые форумчане! 😊 Помогите решить задачку с двумя известными данными? Есть таблица «Исходные пункты» с двумя столбцами,...

Использование хэшсета в задаче выбора всех попарно различных элементов массива
Можно пример использования хэшсета в задачи выбора всех попарно различных элементов массива ? Т.е. чтоб небыло одиннаковых. Я читал, что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru