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

Автор slycelote, 14 лет назад, перевод, По-русски

A. Бросок кубика

Пусть максимум из очков Якко и Вакко -- a. Тогда Дот выиграет, если выбросит не меньше a очков. Вероятность этого равна (6 - (a-1)) / 6. Поскольку a принимает всего 6 значений, ответы можно просто вычислить вручную.


B. Бегущий студент

Общее время, которое понадобится студенту, если он выйдет на i-й остановке, равно ti = bi + si, где bi = xi / vb -- время, которое он проедет на автобусе, а -- время, которое он пройдет от остановки пешком. Нужно выбрать индексы с минимально возможным ti, а среди них -- индекс с минимальным si, то есть, с максимальным bi, то есть (поскольку координаты остановок упорядочены) с максимальным i.

Из-за возможных проблем с точностью условие ti = tj нужно записывать в виде |ti - tj| < ε для достаточно малого ε.

C. Числа Хексадесимал

Полный перебор чисел от 1 до n не пройдет по времени.
Заметим, что все хорошие числа состоят из не более, чем 10 цифр, а каждая цифра равна 0 или 1. Значит, нужно проверить 210 бинарных строк. Каждая из них является числом от 1 до 210 - 1 в двоичной записи. Получаем такой алгоритм: для каждого числа от 1 to 210 - 1 запишем его двоичную запись, прочитаем ее так, как будто бы она была десятичной, и сравним результат с n.

D. Сколько деревьев?

Пусть tnh -- число бинарных деревьев поиска высоты h на n вершинах. Выведем рекуррентное соотношение на tnh. t00 = 1 (пустое дерево), а при i>0 ti0 = t0i = 0.

Возьмем любое дерево высоты h на n вершинах. Пусть в корне записано число m, 1 ≤ m ≤ n. Левое поддерво является бинарным деревом поиска на m-1 вершине, а правое -- на n-m вершинах. Максимум из их высот должен быть равен h-1. Рассмотрим два случая:
1. Высота левого поддерева равна h-1. Таких деревьев tm - 1, h - 1. Правое поддерево в этом случае может иметь любую высоту от 0 до h-1 -- всего таких деревьев . Поскольку правое и левое поддеревья мы выбираем независимо, получаем вариантов.
2. Высота левого поддерева меньше h-1. Таких деревьев ; правое поддерево в этом случае должно иметь высоту h-1, и всего получается вариантов.
Итак, рекуррентная формула такая: .

Значения tnh вычисляются при помощи динамического программирования. Ответ на задачу -- .


E. Интересный граф и яблоки

Забавное кольцо состоит из n вершин и n ребер. Если есть еще какое-то ребро, кроме этих n, то вершины, которые оно соединяет, принадлежат более, чем одному циклу. Итак, интересный граф -- это просто забавное кольцо.
Граф является забавным кольцом если и только если выполнены следующие условия:
A1. Степерь каждой вершины равна 2.
A2. Граф связен.
 Теперь выясним, когда граф не является забавным кольцом, но может быть приведен к такому виду добавлением ребер. Очевидные необходимые условия:
B1. m < n.
B2. В графе нет циклов.
B3. Степени вершин не превосходят 2.
 Будем добавлять ребра так, чтобы эти условия сохранялись, а последовательность ребер была лексикографически минимальна. То есть, добавим ребро (i,j) такое, что:
1. i и j принадлежат разным связным компонентам. (Иначе нарушится B2).
2. Степени вершин i и j меньше 2. (Иначе нарушится B3).
3. Пара (i,j) лексикографически минимальна.
  Посмотрим, что получится, когда мы больше не сможем добавить ребро. Поскольку циклов нет, каждая связная компонента -- дерево, и в нем найдется вершина степени меньше 2. Если есть две связные компоненты, то их можно соединить ребром, не нарушив условий B1-B3. Итак, граф связен, не имеет циклов, и степень каждой вершины равна 2. Это значит, что полученный граф -- простая цепь, и можно соединить ее концы, получив забавный цикл.
 
 Итак, алгоритм:
 1. Проверить условия A1-A2. Если они выполнены, вывести "YES" и 0.
 2. Проверить условия B1-B3. Если они не выполнены, вывести "NO".
 3. Вывести "YES" и n-m.
 4. Добавить ребра описанным способом. При добавлении ребра (i,j) вывести "i j".
 5. Найти вершины i и j степени меньше 2 (они могут совпасть, если n=1). Вывести "i j".
  • Проголосовать: нравится
  • +7
  • Проголосовать: не нравится

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Thanks! =)
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
жалко я английский плохо знаю( приходится переводить в гугл.транслате(
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Thanks!
14 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

D хорошая задача, жалко что не успел решить( 

 Насчет задачи B - достаточно найти наибольшее число k, состоящее из 0 и 1 и меньшее n. Делается это просто - считываем наше число n как строку, и идем по ней с начала. Если встречаем 0 или 1, то ничего не делаем, иначе меняем все символы с позиции  i до конца на '1'. Например: 200 => 111, так как первый символ 2 больше 1.  Затем получившуюся строку рассматриваем как число в двоичной записи, переводим в десятичную и выводим в качестве ответа.

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

you maked good tutorial

author's solution of problem E is looks like the same with yours ;)

  • 14 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    Thanks!
    The first version of my solution was quite a mess, but when I started to write the explanation, I understood that it can be rewritten much clearer. The benefit of writing tutorials :)
14 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
in Problem D, we can calculate via dynamic programming the number of trees with n vertices and height not lower than h directly by using inclusion-exclusion.
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    My algorithm is a bit different from yours, my program computes the number of tree with N nodes and its height is exactly H through DP.
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Hey, can you explain the solution which uses inclusion - exclusion principle directly in Problem D.
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Directly was meant in reference to calculating answers using dynamic programming to the type of question that is asked (number of trees with height not lower than a certain amount). Here is the main loop (the full solution is viewable in the "practice room").

      for (int j = 0; j <= n - 1; ++j)
      mem[n][h] += count(j, std::max(h - 1, 0)) * count(n - 1 - j, 0)
      + count(j, 0) * count(n - 1 - j, std::max(h - 1, 0))
        - count(j, std::max(h - 1, 0)) * count(n - 1 - j, std::max(h - 1, 0));

      Or for each partition of the vertices to the left and right subtrees, the number of trees with height not lower than h is equal to the number of trees with the height of the left subtree not lower than (h - 1) plus the number of trees with the height of the right subtree not lower than (h - 1) less the number of trees with both subtrees of height not lower than (h - 1). The latter term is subtracted, because we have double-counted the solutions with both subtrees of height not lower than h - 1.

      It's similar to what everyone else has.

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
In problem B, I want to know what is the testcase 6?
In the problem statement:
"The second line contains n non-negative integers in ascending order"
so my code read n integer and it fail in testcase 6 but after the contest when I changed it from integer to double I got wrong answer at testcase 23..
This means that testcase 6 contains double..

So, what?

Also I viewed the accepted code of other contestants, I found that it is the same logic of my code, I don't know why my code is wrong answer at testcase 23??

Thanks,
  • 14 лет назад, # ^ |
      Проголосовать: нравится +12 Проголосовать: не нравится

    Yes, your first problem was with rounding. If you cast (double)x[i]/v1 all should be Ok.

    Test #23 checks the condition "If such bus stops (with minimal time arrival) are multiple, choose the bus stop closest to the University".

    3 3 1
    0 1 4
    4 4

    Stops 2 and 3 have the same time, but the 3rd stop is closer to the university.

    Hope this helps you,

    Good luck!

  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    wrong EPS?
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Спасибо за разбор.
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
I'm quite agree with you on that writing a tutorials can make you feel much clearer.
14 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
The solution of E is very nice~
Good Job~
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
long g[10000];
int main()
{
int n,b,c;
cin>>n>>b>>c;
int i;
double min_l;
int index;
double dist,ti,bi,si;
for(i=0;i<n;i++)
{
cin>>g[i];
}
long x,y;
cin>>x>>y;
bi=g[1]/b;
si=sqrt(((g[1]-x)*(g[1]-x)*1.0)+(y*y*1.0))/c;
ti=bi+si;
index=2;
for(i=2;i<n;i++)
{
bi=g[i]/b;
si=sqrt(((g[i]-x)*(g[i]-x)*1.0)+(y*y*1.0))/c;
if(ti>(bi+si)){ti=bi+si;index=i+1;}
}
cout<<index<<"\n";

return 0;
}

почему ВА на 6-м тесте?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    bi=g[1]/b;

      целочисленное деление - 3/2 = 1

    bi=1.0*g[1]/b;

    или

    bi=double(g[1])/b;

    Так же ты не проверяешь условие "Если таких остановок несколько, то выберите ту, от которой расстояние до университета наименьшее". Это 23й тест.


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

    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      спасибо конечно ... но 6 тест все равно не проходит((
      а как  быть с проверкой?по моему первая подходящая остановка будет правильный ответ давать... или нет?
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Нет.

        3 3 1
        0 1 4
        4 4

        В этом тесте время до 2 и 3 одинаково, но третья остановка ближе.


        А здесь "bi=g[i]/b;" тоже исправил?


        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          да но 6-й не проходит тест
          вот весь код:

          include <iostream>
          #include <stdio.h>
          #include <math.h>
          using namespace std;
          long g[10000];
          int main()
          {
          int n,b,c;
          cin>>n>>b>>c;
          int i;
          double min_l;
          int index;
          double dist,ti,bi,si;
          for(i=0;i<n;i++)
          {
          cin>>g[i];
          }
          long x,y;
          cin>>x>>y;
          bi=1.0*g[1]/b;
          si=sqrt(((g[1]-x)*(g[1]-x)*1.0)+(y*y*1.0))/c;
          ti=bi+si;
          index=2;
          for(i=2;i<n;i++)
          {
          bi=g[i]/b;
          si=sqrt(((g[i]-x)*(g[i]-x)*1.0)+(y*y*1.0))/c;
          if(ti>(bi+si)){ti=bi+si;index=i+1;}
          else if(ti==(bi+si))
          {
          int doun1,doun2;
          doun1=(x-g[index-1])*(x-g[index-1])+(y*y);
          doun2=(x-g[i])*(x-g[i])+(y*y);
          if(doun2<doun1){ti=bi+si;index=i+1;}
          }
          }
          cout<<index<<"\n";

          return 0;
          }
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

              bi=g[i]/b;

            надо заменить на bi = 1.0*g[i]/b;

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

              bi=g[i]/b;

            надо заменить на bi = 1.0*g[i]/b;

            • 14 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится
              я так и сделал:)
              в коде это написанно
              • 14 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится
                ???
                for(i=2;i<n;i++)
                {
                bi=g[i]/b;
                • 14 лет назад, # ^ |
                    Проголосовать: нравится 0 Проголосовать: не нравится
                  я заменил в этом фрагменте кода "*1.0" но всё равно ВА на 6-м тесте((
                  • 14 лет назад, # ^ |
                      Проголосовать: нравится 0 Проголосовать: не нравится
                    вот тут происходит overflow лонга:
                    si=sqrt(((g[i]-x)*(g[i]-x)*1.0)+(y*y*1.0))/c;

                    надо сначала умножать на 1.0, но лучше просто объявить все переменные даблом.
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
ещё...Значения tnh вычисляются при помощи динамического программирования. Ответ на задачу -- .-что означает эта формула?чему равно  tni . ???я так и не понял(
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
да я это понимаю про сумму,рекуррентное соотношение но не понял чему равно tn,h,tn,h+1 . как искать эти значения?!
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Что-то я в замешательстве)
    tnh -- число бинарных деревьев поиска высоты h на n вершинах
    Вычисляется по выведенным рекуррентным соотношениям.

    Что именно непонятно?
14 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится
Another solution to prob C that runs in O(logN) is to take the maximum number X, formed only from '0's and '1's, that is smaller than N. Now we can treat X as in base 2 and the answer is it converted to base 10.
example:
N = 101003021
X = 101001111
so, answer = 335
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Why the complexity of this solution is O(logN)? I can see the solution with comlexity O(L), where L is the length of input string.(sorry for bad English)
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Why the complexity of this solution is O(logN)? I can see the solution with comlexity O(L), where L is the length of input string.(sorry for bad English)
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
For problem C there is also an other approach. Read the number as a string. For each letter you make the follwing decision: If the number is greater than one, than all the other numbers in binary representation will also be one, otherwise if it is zero, the number representation is zero, and if it is one, it is one.
»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Problem E if input data ocuur a situation like this: n = 8 m = 9 1 2 2 3 3 1 3 4 4 5 5 6 6 4 is it yes?

»
6 лет назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

in problem D tutorial.

neither of the 2 cases takes a height where height of left subtree or right subtree is greater than h-1.

why isn't this possible that there may be cases where either the LS or RS has height greater than h?

Can anyone please tell...

  • »
    »
    6 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    You are deriving recursive formula for a tree with n nodes and max height h in the current step. This n and h vary from (0..N) and (0..N) while calculating the dp table. When you have considered the tree with max height h then its left subtree can have max height h — 1 only.

    Later you add up values in the dp table for trees of heights of (H..N).

    • »
      »
      »
      6 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      yes .. i understood the rest part but where in the question it was mentioned that

      height can't be greater than h.. it is written in the question that height can't be

      lower than h but tutorial solve the question by taking max height upto h not more

      than that .. here is the difference i was mentioning ..

      otherwise the question is just similar of finding optimal binary search tree

      • »
        »
        »
        »
        6 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Here we are solving for a general n and h. Not the ones mentioned in the question. We are summing up over all the possible subtrees which will have height less than h again because we are considering the tree with max height h.

»
2 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

In problem D, in case 2 of the above solution, shouldn't the height of the left subtree be less than h and not h-1 ?

  • »
    »
    2 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Height of the left subtree — less than h-1. Height of the right subtree — exactly h-1 (otherwise height of the whole tree is less than h).