Блог пользователя dalex

Автор dalex, 14 лет назад, По-русски
Собственно, здравствуйте, уважаемые читатели. Это мой первый пост на этом сайте, и связан он, разумеется, с четвертьфиналом 18-23 октября в Саратове, который на самом деле называется первенством Южного подрегиона NEERC.

Вероятно, все уже видели монитор соревнований - там команда Samara SAU #2 заметно опередила мою команду Samara SAU #1. Это не случайность, просто при регистрации человек, ответственный за нее, решил пошутить и поменять нас местами, потому что он хотел отсортировать команды по возрасту. Так что реально сильнейшей была вторая команда, а наши шансы на проход я оценивал примерно 50 на 50.

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

Рассказ, пожалуй, надо начать с 20 октября, когда прошел пробный тур и раздали условия Code Game Challenge. О пробном туре у меня одно замечание: меня и мою команду очень порадовала тестирующая система. При написании java-класса, реализующего Runnable и дальнейшем создании нового потока тестирующая система давала верный вердикт RE при выбрасывании исключения. А вот на Тимусе, например, дают WA вместо RE.

Посмотрев задания Code Game Challenge, мы очень обрадовались: это снова танки, а не унылые гонки. Точнее, это были танки двухлетней давности без баз и трения.
На самом Code Game Challenge мы сначала написали стрельбу, на это ушло примерно час. Мы просто сделали все то же самое, что и 2 года назад, когда наш танк занял 7 место. Этот алгоритм себя оправдал: стрелял наш IDDQD идеально. А вот хорошее движение написать не получилось: наверняка все видели, как наш танк тупил.
Было обидно, что нам не везло с случайными бонусами. За 10 минут до конца соревнования мы тестили свой ховеркрафт на рандомах в Global Test, и он примерно в 80% случаев набирал более 100 очков и занимал 1 место. За 6 раундов настоящего Code Game это удалось лишь в самой первой игре. Возможно, при большем везении мы попали бы в призы.
Зато отлично выступила наша вторая и сильнейшая команда. Их ховеркрафт рвал нашего IDDQD один на один примерно в 70% случаев. Мы предполагали, что это серьезная заявка на победу - так и вышло. Ховеркрафт с загадочным названием Natasha Fan Club, названный в честь местной богини программирования, не только идеально стрелял, но и превосходно ездил и собирал бонусы, и в итоге победил, выиграв 8 поединков из 9 и уступив еще в одном лишь одно очко.
А наша третья команда с креативным названием 123456789 заняла шестое место, обогнав наш невезучий ховеркрафт, который закончил турнир на 16 месте.
Я снимал на сотовый второй и третий раунды (т.е. когда осталось 32 ховеркрафта и финал соответственно), и они уже доступны для просмотра (пока на Rutube). Хотя было бы круто, если бы организаторы выложили оригинальное видео, я не вижу причин, почему этого не делать.

Сам контест для нашей команды прошел в режиме злостного отупения. Вначале мы написали задачу F (про лифт), но получили TLE. Конечно, это было зацикливание. Мой просчет... Потом набрали задачу B (про кубики), сдали таки F и J (про буйки, где один из моих партнеров вовремя сообразил, что надо оставлять на месте ровно два буйка). Затем я целый час решал E (про мужика, которого везут с закрытыми глазами), вовремя не заметив нормальное решение в 3 цикла for. Первый неверный сабмит по E получил TLE, хотя работать должен был вроде бы недолго. А второй неверный сабмит произошел из-за глупейшего бага, недописанной строчки. Потом мы зачем-то написали эвристику для C, cловившую WA #19, и сдали D (про Николая и Владимира) с второй попытки (ага, естественно, ребро надо добавлять только в одну сторону).
Итак, за 3 часа мы сдали 5 задач, а наша первая (на мониторе - вторая) команда сдала шесть. В дальнейшем мы так ничего и не сдали, а за час до конца соревнований были на 13 месте, если исключить стоящие выше нас лишние саратовские команды. Непосредственно после контеста мы узнали, что сидевшие напротив нас волгоградцы решили две задачи за последний час и обогнали нас - мы стали четырнадцатыми, последним выходящим местом.
На выходе нас немножко успокоили, сказав, что мы были последними из тех, кто решил пять задач, и что команды, решившие четыре задачи, отставали от нас по времени - им надо было делать две. Этого не произошло, и мы проскочили в Питер, не решив ни одной трудной задачи. А вообще непонятно, почему мы не начали писать G и K.

Результат был отпразднован, разбор задач прослушан, и пора было уезжать. Мы решили посидеть на лавочках на территории университета и уйти, как только до отправления поезда останется час. Там было весело: на нас целый час набигали две пьяные девочки, Алиса и Оля. Они никак не могли поверить, что мы ждем поезда, и все время пытались унести с собой рули, выигранные в Code Game Challenge. В итоге они порвали ручку у коробки руля и зохавали два бейджика. Впрочем, это нас не огорчило, и мы уехали домой, в Самару. А я еще и написал этот пост.

UPD: Видео Code Game Challenge залито на Rutube: http://rutube.ru/tracks/3703952.html?v=74c4d34409fa2e52a8c439a3039b7f03 и Вконтакте: http://vkontakte.ru/video7104349_154275450, не ругайте меня за возможные неадекватные комментарии...
  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Жжош
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

"При написании java-класса, реализующего Runnable и дальнейшем создании нового потока тестирующая система давала верный вердикт RE при выбрасывании исключения. А вот на Тимусе, например, дают WA вместо RE."

А разве порядочная система и не должна выдавать RE, когда срабатывает исключение?

На 1/4 Центрального региона тоже была проблема в том, что если создавать поток и потом в нём например специально где то throw new Error(); то их система не успевала отследить выброс ошибки, поток по тихому закрывается и мы получаем пустой вывод, например, -> WA вместо RE, который мы специально хотели бы получить при каких то условиях. Так что мне кажется, что если в программе мы хотим, чтобы ошибка была выкинута и хотим получить  RE - то мы и должны были получать RE вне зависимости от того как мы реализовали логику работы программы.

  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    http://paste.org.ru/?3onj05
    Попробуйте сдать на Тимусе. Будет WA вместо Crash.
    А в Саратове такой ерунды не было, что очень порадовало.
  • 14 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    Вот такая болванка применялась нами на 1/4

    import java.io.*;
    import java.util.*;

    public class RybinskA {

    static class Run extends Thread {

    Scanner in;
    PrintWriter out;

    void solve() {
    for (int i = 0; i < 1000000000; i++) {}
    int x = 0;
    x /= x;
    }

    public void run() {
    try {
    in = new Scanner(new InputStreamReader(new FileInputStream("input.txt"), "latin1"));
    out = new PrintWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), "latin1"));
    try {
    solve();
    } finally {
    out.close();
    }
    } catch (Throwable t) {
    // t.printStackTrace();
    System.exit(1);
    }
    }
    }

    public static void main(String args[]) {
    new Thread(null, new Run(), "R", 64000000).start();
    }
    }

    Она нам гарантировала получение RE в случе если в потоке что то нафигнётся.

  • 14 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    Для того, чтобы отлавливать исключения, произошедшие в каком-то дочернем потоке, не достаточно просто смотреть на код возврата процесса java (как делается в некоторых online judge'ах). Можно запускать решения, например, следующим способом: http://paste.org.ru/?2kd6oh
    Здесь Solution - класс, предоставленный участником. Соответственно, запускаем не его, а JavaSolutionsRunner, который в свою очередь уже запустит решение участника и установит свой обработчик исключений, который завершит процесс java-машины с ненулевым кодом возврата.
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
А если делать так, тоже будет WA:

run() {
try{
//some code
}
catch(Exception) {failed =true;}
}

main(){
//в самом конце
if(failed)
throw new RuntimeException();
}
  • 14 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    Я не знаю, что у тебя в main-е до "//в самом конце", но обычно тут пишут что-то типа "new Thread(new Solution()).start()". Казалось бы, после вызова start() управление main-у передается сразу же, поэтому проверка на failed бесполезна, так как во вновь запущенном потоке еще ничего не произошло. Если ты потоку какой-нибудь join делаешь, или еще как-нибудь ждешь его, то нормально, иначе проверка бесполезна.