Задача А — Ваня и карточки
Решение задачи заключается в том, что бы просуммировать все числа которые записанны на карточках, и пытатся эту сумму свести к нулю за минимальное количество операций, используя операции +х и -х.
Задача Б — Сережа и контесты
Поскольку ограничения в этой задаче не очень большие, то можно написать простой жадный алгоритм. Вначале обозначить в массиве номера контестов которые запомнил Сережа, как занятые. Для нахождения максимального количества контестов, нужно посмотреть сколько ячеек, номера которых меньше за х, еще не заняты. Это и будет максимальный ответ. Для нахождения минимального количества, нужно пройтись по массиву и пытаться как можно больше вставлять контести типа "Div1+Div2" — это можно будет сделать, если будут свободны две подряд ячейки нашего массива. Если же нельзя вставить контест типа "Div1+Div2", тогда в свободный номер забиваем контест типа "Div2". Проделав такие операции, мы узнаем минимальное количество контестов.
Задача С — Команда
Эту задачу можно было делать несколькими способами, я расскажу Вам об одном из них. Обозначим количество карточек на которых записано 0 — n, а количество карточек на которых записано 1 — m. Тогда можно сделать нужную последовательность когда (n - 1 <= m && m <= 2 * (n + 1))
.
Если же все таки можно сделать нужную последовательность, рассмотрим 3 случая:
(m == n - 1)
. Тогда выводим единички и нули через один, но обязательно начинаем с 0.(m == n)
. Тогда выводим единички и нули через один, но тут мы можем начинать и с 0, и с 1(m >= n + 1 && m <= 2 * (n + 1))
. В этом случае нам обязательно нужно начинать с 1 и выводит единички и нули через один. В конце тоже должна быть обязательно единичка. Если мы доходим до конца но единички еще остались, то пытаемся прилепить по одной единичке к тем что у нас есть. Например у нас было 10101, у нас осталось две единички, делаем сначала 110101, а потом 1101101. После таких операций мы получим правильный ответ.
На счет того что некоторые решения не проходили 11 тест на FPC, но проходили на Delphi, то в этой ситуации участник должен был понимать, что на Паскале вывод займет достаточно много времени, и он должен был или как-то оптимизировать решение, или же написать в другой среде.
Задача Д — Роман и числа
Эту задачу можно отнести к теме динамическое программирование. Используя маски для запоминания взятых уже цифр мы можем с помощью динамики очень легко решить эту задачу. Пускай у нас будет динамика — dp[i][x]
, где i — маска перестановки, а х — это остаток от деления данной перестановки на m. Будем перебирать сами маски и остаток. При добавлении цифры a[j] будем использовать такой переход:
dp[i or (1 shl (j-1)),(x*10+a[j]) mod m] := dp[i or (1 shl (j-1)),(x*10+a[j]) mod m] + dp[i,x];
Обязательно в конце нужно ответ поделить на факториал количества вхождений каждой цифры, поскольку у нас может получиться несколько одинаковых перестановок, а это недопустимо.
for i:=0 to 9 do
for j:=2 to b[i] do
ans:=ans div int64(j);
Для улучшения времени работы программы, можно приписывать одинаковые цифры в порядке их следования в числе.
Задача Е — Олимпиада
Для начала в этой задаче нужно было понять, что пару учеников мы могли задавать в виде прямоугольника. Тогда расстояние между учениками это диагональ прямоугольника. Пускай первый ученик находится в точке (x1,y1), а второй в точке (x2,y2). В этом случае нам нужно что бы выполнялись два условия:
L*L <= (abs(x1-x2)*abs(x1-x2) + abs(y1-y2)*abs(y1-y2)) <= R*R
gcd(abs(x1-x2),abs(y1-y2)) == 1
Так как поле может быть 100000*100000, то понятно что перебор значений abs(x1-x2)
и abs(y1-y2)
займет достаточно много времени. Поэтому будем перебирать только одно значение, а количество вхождений второго вычислять из нашего неравенства:
L*L <= (abs(x1-x2)*abs(x1-x2) + abs(y1-y2)*abs(y1-y2)) <= R*R
L*L - abs(x1-x2)*abs(x1-x2) <= abs(y1-y2)*abs(y1-y2) <= R*R - abs(x1-x2)*abs(x1-x2)
Количество вариантов разместить наш квадрат на поле n*m будет (n-abs(x1-x2)+1)*(m-abs(y1-y2)+1)
. Вычисление суммы (n-abs(x1-x2)+1)
не очень сложное, но вот что бы вычислить сумму (m-abs(y1-y2)+1)
, где (L*L<=abs(x1-x2)*abs(x1-x2)<=abs(y1-y2)*abs(y1-y2)<=R*R-abs(x1-x2)*abs(x1-x2))
, будет немного тяжелее. Нужно использовать метод включения-исключения и найти сумму чисел на отрезке, которые делятся хотя бы на один из простых множителей нашего числа abs(x1-x2)
.
К сожалению, по моей вине, в раунд попала задача которая ранее была использована на другом соревновании. Так как это не соответствует правилам Codeforces, задача E будет удалена.
Хочу сказать спасибо Сергею Орышичу (Oryshych) за помощь в написании разбора.
А что есть v в задаче Д?
D, ответ поделить на количество вхождений каждой цифры — здесь должно быть "на факториалы количества", правильно?
Можно в разбор добавить так же ссылки на авторские исходники? Так будет проще понять сложные моменты. К примеру, Е без исходника как-то очень трудно воспринимается.
dp[i or (1 shl (j-1)),(x*10+a[j]) mod m] := dp[i or (1 shl (j-1)),(x*10+a[j]) mod m] + dp[i,x];
И все сразу стало понятно...
Я долго пытался найти различие между выражением "dp[i or (1 shl (j-1)),(x*10+a[j]) mod m]" и выражением "dp[i or (1 shl (j-1)),(x*10+a[j]) mod m]"
Автор выразил dp[a][b] через dp[a][b] + dp[c][d]. Круто.
When will the editorials be published ?
Exactly :D
Не понял решения D,E. Объясните, плз.
А в задаче С на FPC достаточно было склеить строку-ответ и вывести ее в самом конце)
да в задаче С можно было делать и так. Просто если сразу выводить посимвольно, то это занимало много времени.
Возник вопрос по задаче D. Есть две почти одинаковые отправки: 5991586 и 5991163. Отличие одно: в первой — массив w[2^18][100], во второй — w[100][2^18] (соответственно меняется подсчет). В первом случае решение проходит за 500 с небольшим мс, во втором — лимит по времени не на самом тяжелом тесте. Почему такая большая разница (как минимум, в 8 раз)?
Может эта статья поможет http://habrahabr.ru/post/211747/
Видимо, частые выходы за пределы кэш-памяти
I know the problem D should be dynamic programming, but I still don't know how to solve this problem
I know the problem D should be dynamic programming, but I still don't know how to solve this problem
I think that you should use
Unable to parse markup [type=CF_TEX]
to write mathematics formulas.I think that you should use
Unable to parse markup [type=CF_TEX]
to write mathematics formulas.It would be good if authors solution is in C/C++ or java.
В "B" создал строку из 1-иц и 0-ов, где нолики — незанято. Тогда ответ составил количество успешных совпадений при жадном поиске c регулярным выражением (regexp) по всей строке (global) — /00|0/g и /0/g. Perl код 5990466.
For problem D can you tell me what 'mask of reshuffle' means? sorry i don't get the solution clearly
Bitmask for this problem let you know that whether the i-th digit of the given number has been used or not. For example, if my number is 1223 and my mask is 0100, that mean I have constructed number 2. If my mask is 1110, that mean I have constructed the number which is a "permutation" of number 122.
Sorry, but I couldn't understand the editorial for Problem D. Others are also very short. Can you elaborate a little? Is there any similar problem at UVA or TopCoder or any other online judge? If you know please give the numbers if possible,
In the end we must answer to divide by the factorial number of occurrences of each digit.
What does this even mean ? The english is not correct and I don't understand why we must divide de result ?
It means that e.g. in 212232, here size of number(212232) is 6 digits. 2 is coming 4 times. so in the frequency[10] array we are setting frequency[2] = 4. when we are calculating different numbers via permutation we are thinking that there are factorial(6) new numbers but as in mathematics actually only 6!/4! new numbers are generated. that's why after all the calculation we are dividing the result by factorial(i) for all the values of i from i=0 to i=9. reason is that 8 different permutations of abc are abc acb bac bca cab cba but for 232 as 232 223 322 are the only 3 ( 3!/2! = 6/2 = 3)distinct permutations. Hope you understood the point.
For problem D,
I have converted the dp equation to c++
Is my understanding true that dp[i][x] represent the answer for the number whose elements are selected by the i bit mask with divisor as x. In other words it is the answer to the number given by the selected digits and when the divisor is x.
If someone can explain the dp equation in simple terms, that would be a great help. I can only understand that the number with one digit less is somehow related to the number with one digit more.
This is the solution:
say input is {15354} & m=9. The idea is dp[i][j] will contain sum of all cases for particular instance of problem. Say initially, you have counted number 3 only i.e. i = {00100} & j = {3}. Now you may go to i = {10100} (by using 1) or {01100} (by using 5) or {00110} (by using 5) or {00101} (by using 4).
All these will be generated in loop-k. If you choose 1 then j = ((3)*10+1)%m i.e. ((earlier value of j)*10 + current value of j)%m, similarly we can calculate 5 or 4.
Coverage of all cases is done like this: initially we set for all single digits in the given number, so i-variable will be executing for {00001, 00010, 00100, 01000, 10000}
Now to reach 01110 we have following ways:
01000 --> 01100 --> 011100 & 01000 --> 00100 --> 011100 {this will be covered while using i = 01000 first & then applying above logic}
00100 --> 01100 --> 011100 & 00100 --> 00110 --> 011100{this will be covered while using i = 00100 first & then applying above logic}
00010 --> 00110 --> 011100 & 00010 --> 01010 --> 011100{this will be covered while using i = 00010 first & then applying above logic}
Now if extend this logic to every case, you will see that indeed all the permutation has been covered. To sum up, with each combination we need to do OR operation with all possible Shifts of 1 so that next set of combination is generated for some specific permutations & similarly all the permutation is being generated.
sagar,
the state dp[i][j] is the total numbers close to the number determined by the i mask modulo j, correct?
yes.
is j the modulo or the actual number represented by the i mask..sorry got confused.
j here is always modulo, & the beauty is you can always calculate next modulo after taking any other digit into account.
i am not getting what the j loop is doing..why is it cycling through all modulo from 0 to m..can you plz clarify that?
for(int j=0;j<m;j++)
the thing is you do not actually know which modulus you will get when you will count upto a state like in case of 3, d[00100][3] = 1, but if say we reach a state i = 00111 we could have multiple modulo because of the sequence we took & we need this modulo at last. So make this modulus j a part of dp state itself & update it.
maybe i am not understanding some properties of modular arithmetic but i am not getting why are we shifting the mod left. Couldn't we just do f[k]%m instead of (j*10+f[k])%m?
dp[i|(1<<k)][(j*10+f[k])%m]+=dp[i][j];
no we could not, becoz f[k]%m will always be same for a particular k, but real modulus depends on sequence of digits we have chosen.
Really sagar.topcoder, you explained wonderfully. I appreciate your efforts.
It's ironic how some problem setters are so smart at coming up with problems, but so lousy at explaining solutions.
I'm sorry I tried. If you do not understand something, write me.
UPD: Sorry, my bad, I didn't read problem statement correctly.
I don't know if anyone will pay attention to my comment now, but I was doing Problem C while practicing and found that the alternative solution is not being considered by the judge.
In case 5, ie.
3 4
, my code outputs1101101
but the judge declares it's wrong, citing the Jury's solution as1010101
and message aswrong answer. The number of ones should be 4, but found 5; The number of zeros should be 3, but found 2;
My submission is here: 11114404
After re-reading the question several times, I'm quite sure my answer satisfies all constraints mentioned in problem.
1101101
doesn't have more than 2 adj. 1 and no more than 1 adj. 0.I request the author, EG0R to kindly look into this problem and resolve this issue(and in case it's my own mistake, point it out.). :)
Ladies and gentlemen, is this the highest dimensional dp ever written ? http://codeforces.net/contest/401/submission/22059230
Sorry it's not ==> My submission
For problem D , my submission get time limit on test 35 and I can't find how to optimize my solution.
This is my submission 36532811 . Any help please !
I think the implementation for C is quite cumbersome.
Let $$$n_0$$$: the number of 0, $$$n_1$$$ the number of 1.
$$$n_1$$$ must be in constraint $$$n_0-1 \leq n_1 \leq 2n_0+2$$$, otherwise there is no solution.
I will solve for range: $$$n_0 \leq n_1 \leq 2n_0$$$, (you should see my code to understand correctly)
Let $$$a$$$ is the number of patterns '110', $$$b$$$ is the number of patterns '10', so:
We are solving in range $$$n_0 \leq n_1 \leq 2n_0$$$, therefore $$$a, b \leq 0$$$. With $$$a, b$$$ after solving two equations. We construct a string answer following the greedy strategy. Up to now, the string answer always start with '1' and end with '0'.
I add some padding characters to get answer.
if $$$n_1 = n_0 - 1$$$, add '0' to start of above string.
if $$$n_1 > 2n_0$$$, add $$$(2n_0 - n_1)$$$ '1' to the end of string.
My solution
a+b=n0 a+2b=n1
what s the logic behind these equations ?
'10' contains 1 '1' and 1 '0'. And we have a '10'.
'110' contains 2 '1' and 1 '0'. And we have b '110'.
So n0 = a+b and n1 = a + 2b
what s the relation between pattern 110 and 10 and the number of n0 , n0 consists of only 0 elements , and these patterns includes 1 , and thank you
c ..i think there would be a better soln than this..31ms i got!!!
void solve() { ll n,m; cin>>n>>m; if(m>2*n+2 || n>m+1) cout<<"-1"<<endl; else if(n==m) { string s=""; for(ll i=1;i<=m;i++) s+="10"; cout<<s<<endl; return; } else if(n==m+1) { string s="0"; for(ll i=1;i<=m;i++) s+="10"; cout<<s<<endl; return;
}
can anyone explain how to solve the D problem if I am using normal masking it is giving me tle because 2^18 for mask and 100 for the reminder and for each case we will check at all digit that is 18 so I think there will better solution or how should I optimize this.
" then we must start form one and we derive the ones and zeros in one, but in the end must be one. And if we in the end and we have ones, then we try to stick to one unit so that we have. For example, we have 10101 and two ones, after we have 110101 and one ones, and then we have 1101101."
Crap explanation. Better learn some english first before writing editorials.