A. Следующий тест
Эта простая задача решается следующим образом. Заведем массив boolean used[1..3001] и заинициализируем его значениями false. Для каждого из n данных нам чисел, соответствующий элемент массива used присвоем true. Далее пройдем по массиву, начиная с 1 и найдем первое число, для которого значение used - false. Это и есть ответ.
B. Турнир
Для решения данной задачи сначала найдем такие числа A и B, которые встретились во входных данных не n - 1, а n - 2 раз. Если переформулировать условие, то можно заметить, что отношение победившего и проигравшего транзитивно - то есть если X, выиграл Y, а Y выиграл Z, то X выиграл Z. Значит, чтобы определить кто круче - A или B, попытаемся найти такое C, у которого результат игры с A и результат игры с B различный. Если мы нашли такое С, то того игрока, который выиграл, надо вывести первым. Если такого С не существует, то любой исход матча А против B удовлетворяет условиям задачи.
C. Неотсортированная подпоследовательность
Сначала заметим, что ответ всегда либо 0, либо состоит из 3-х элементов. Однако за кубическое время искать ответ слишком долго. Вот решение за линейное время.
Будем идти по последовательности и во время каждой итерации поддерживать минимум на префиксе. Когда мы рассматриваем текущий элемент, достаточно проверить не образовавает ли этот элемент хорошую подпоследовательность с текущими максимумом и минимумом. Это не сразу очевидно, но легко доказывается. Подумайте сами над этим как домашнее задание.
D. Кольцевая 2
Рассмотрим все дороги как отрезки на числовой прямой. Дороге из города a в город b будет соответствовать отрезок [min(a, b), max(a, b)]. Для каждой пары отрезков есть 3 варианта расположения: оба конца одного отрезка внутри второго, оба конца одного отрезка вне второго и только один из концов одного внутри второго. В первых двух случаях положение дорог, соответствующих отрезкам не зависимы друг от друга. В третьем же случае дороги должны проходить по разные стороны от кольца.
Построим такой граф: вершины будут соответствовать дорогам, а ребро между вершинами i и j будет означать, что эти дороги должны лежать по разные стороны. Мы свели задачу к следующей: есть неориентированный граф. Необходимо раскрасить все его вершины в 2 цвета так, чтобы никакие 2 вершины одинакового цвета не соединялись ребром. Это делаеться при помощи, например, dfs'са. Изначально цвет каждой вершины - -1. Циклом for пойдем по вершинам. Если цикн натыкается на -1-вершину, то присваивает ей цвет 0 и запускает из неё dfs. dfs просматривает все соседи, переданной ему вершины. Если видит -1-вершину, то красит её в цвет, противоположный цвету текущей вершины и запускается из неё, иначе он сравнивает цвета текущей вершины и рассматриваемого соседа. Если они совпали, то выводим Impossible. После такого dfs'а получим ответ.
E. Число с заданным количеством делителей
Рассмотрим число, являющееся ответом и разложим его на простые множители. Получим такое произведение p1a1· p2a2· ... · pkak. Произведение по i всех ai + 1 и будет числом делителей. То есть если мы возьмем десять простых и перемножим, то уже получим число с 1024-мя делитемяли. Отсюда следует, что нам понадодиться максимум первые десять простых чисел для того, чтобы построить нужное число.
Рассмотрим следующую динамику: d[i][j] = наименьшее число с i делителями и составленное из первых j простых чисел. Для вычисления состояния (i, j) переберем степень с которой j-е простое число войдет в ответ. Если j-е простое число входит со степенью k, то d[i][j] = d[i / (k + 1)][j - 1] * prime[j]k. По всем возможным переходам надо выбрать минимум.
Во время реализации надо быть предельно осторожным, так как все вычисления происходят на грани переполнения.
На этом все. Надеюсь, вы теперь разберетесь в задачах, дорешаете их и на следущем контесте перейдете в первый дивизион. Любые замечания и вопросы оставляйте в комментах. Если что-то не так - исправлю. С уважением, Иван.
нельзя ли узнать тест 11 на задачу С.
Очень хочется понять на чем завалилось решение.
Не знаю что за тест.
У тебя такое же решение или другое?
У меня также не прошел 11 тест. Идея решения: умножаем разность первого числа и предпоследнего на разность предпоследнего и последнего. Если она отрицательна, то подпоследовательность найдена. Наверно в 11 тесте эти числа оказались порядка 10 6 , -10 6 и 10 6 Произведение в этом случае выйдет за пределы int64.
Код на шарпе:
int n = int.Parse(Console.ReadLine());
string[] s = Console.ReadLine().Split(' ');
int[] a = new int[3001];
for (int i = 0; i < n; i++)
{
int c = int.Parse(s[i]);
a[c] = 1;
}
for (int i = 1; i < 3001; i++)
{
if (a[i] == 0)
{
Console.WriteLine(i);
return;
}
}
Выложите тест 23, если не сложно.
Ты ничего не выводишь.
Ответ может быть равен 3001, если первые 3000 чисел использованы.
I just read the article, but it's in Russian, now English!!
BTW, To avoid overflow you can use this idea - If A*B>C then A>C/B.
C++ has "long long int" type that can hold numbers up to 9·1018.
It is said that answer is lower than 1018. So when prime[j]k becomes to big, I just break from the cycle. Also, because 10-th prime is only 29 me can assume, that if some var is overflowed, this var is negative. So check this also.
int main()
{
int Nomer[2][1225], A[2], Buf[2500], chislo, test, N, i, j, k=0, m=0, q;
cin>>chislo;
N=chislo*(chislo-1)/2;
for (i=0; i<N-1; i++)
cin>>Nomer[0][i]>>Nomer[1][i];
m=0;
for (i=0; i<2; i++)
for (j=0; j<N-1; j++)
{
Buf[m]=Nomer[i][j];
m++;
}
for(i=0; i<m-1; i++)
for(j=i; j<m; j++)
if(Buf[i]>Buf[j])
{
test=Buf[i];
Buf[i]=Buf[j];
Buf[j]=test;
}
j=Buf[0];
i=1;
q=0;
while(i<=m)
{
k=1;
while((j==Buf[i])&&(i<=m))
{
k++;
i++;
}
if (k<chislo-1)
{
A[q]=j;
q++;
}
j=Buf[i];
i++;
}
cout<<A[0]<<" "<<A[1]<<endl;
system("Pause");
return 0;
}
Во-первых
while((j==Buf[i])&&(i<=m)) - проверки надо делать в другом порядке. Иначе выйдешь за грань массива.
Во-вторых
Ты должен вывести недостоющую запись не в любом порядке, а так, чтобы сначала шел победитель, а потом проигравшый. Твоя программа это нигде не учитывает.
For problem Div2D, could anyone explain why two color painting gives a correct answer and what the logic behind it is? Thanks.
EDIT 2: Fellow coder helped understanding the idea. SOLVED.