Неверный вывод для USACO декабрь 2018 Бронза назад вперед

Чтобы показать разделители thausand, вы можете отформатировать значения в строках и поместить там разделитель. Это работает с функцией формата - Format(10000, "#,##0.00"). Затем значения должны быть сохранены как массив строк, и этот массив является тем, который передается в качестве источника для UserForm.Combobox1.List:

Sub UserForm_Activate()

    Dim myArr As Variant
    Dim myRng As Range

    Set myRng = Range("A1:A4")
    ReDim myArr(myRng.Cells.Count)

    Dim i As Long
    For i = LBound(myArr) To UBound(myArr)
        myArr(i) = Format(myRng.Cells(i + 1), "#,##0.00")
    Next i

    ComboBox1.List = myArr

End Sub

Вот как это выглядит:

0
задан ggorlen 19 January 2019 в 23:44
поделиться

1 ответ

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

Однако, чтобы это работало, каждый раз, когда вы несете ведро из сарая и возвращаетесь в детское состояние, вам нужно «отменить» молоко, которое было передано, когда вы вернетесь в родительское состояние. Таким образом, когда вы попытаетесь взять другое ведро на следующей итерации, у вас будет свежее состояние для работы без загрязнения от предыдущих рекурсивных симуляций.

Рассмотрим следующие строки:

two.add(x);
one.remove(i);
wednesday(milk - x, one, two);

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

Вместо этого попробуйте восстановить состояние следующим образом:

two.add(x);
one.remove(i);
wednesday(milk - x, one, two);
one.add(i, two.remove(two.size()-1)); // undo the milk transfer

При таком подходе после вызова wednesday() количество молока и ведра восстанавливаются в исходное состояние и будущие итерации цикла этот тест других ковшей будет делать это точно.

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

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

Нет причин иметь разные функции для каждого дня недели, потому что одна и та же процедура выполняется каждый день, а именно, рекурсивно пытаться перенести каждое доступное ведро в другой резервуар. Вы можете использовать переменную day для представления текущего дня и увеличивать ее при каждом рекурсивном вызове. Если вы начинаете в день 0, ваш рекурсивный базовый случай - это когда day == 4, и в этот момент вы можете записать окончательное значение milk для этой последовательности выбора сегмента. Чтобы определить, с какого сарая Farmer Brown стартует в данный день, вы можете либо взять модуль day, либо поменять местами массивы источника и приемника для каждого рекурсивного вызова и найти способ добавлять или вычитать количество молока в зависимости от того ты в сарае.

И наконец, if(!poss.contains(add)) - это линейная процедура, которая требует рассмотрения до каждого элемента в списке и собирается нанести огромный удар по производительности при вычислении результатов. Используйте HashSet для сохранения уникальных возможных результатов. Размер этого сета - ваш окончательный результат.

0
ответ дан ggorlen 19 January 2019 в 23:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: