CodeChef is a non-commercial competitive programming community
Login
Username (New User? Signup) Password (Forgot Password?)
Signup
Login or
Signup with
Connect
Note
  • Publicize your achievements on your Facebook Wall.
  • Challenge your friends or ask them for help.

Site Navigation

  • PRACTICE
    • Easy
    • Medium
    • Hard
    • Challenge
    • Peer
  • COMPETE
    • All Contests
    • June Long 2012
    • May Cook-Off
    • May Long 2012
  • DISCUSS
    • Forums
    • Blog
    • Wiki
    • Facebook
    • Twitter
  • COMMUNITY
    • CodeChef Meetups
    • Campus Chapters
    • Host your Contest
    • User Groups
    • CodeChef TechTalks
    • All Educational Initiatives
  • HELP
    • Frequently Asked Questions
    • FAQ for problem setters
    • Problem Setting
    • Tutorials
    • Long Contest Ranks
    • Short Contest Ranks
    • Event Calendar
  • ABOUT
    • About CodeChef
    • Team CodeChef
    • Press Room
    • CodeChef Financials
    • CodeChef Sponsorships
    • CEO's Corner
    • Contact Us
    • About Directi
Home » Wiki » November 2011 Contest Problem Editorials

November 2011 Contest Problem Editorials

 

Problem Tester for the November 2011 Contest was Tolstikov Aleksey.

-------------------------------------------------------------------------------------------------------

DOMNOCUT (written by Anton Lunyov)


You can view the editorial here.

 

You can view the solution here:

Problem Setter's solution

-------------------------------------------------------

HAREJUMP (written by Saransh Bansal)

 

The question requires some Mathematics and the whole system can be seen as State Transitions. The number of ways to reach a state(X) is equal to number of ways of reaching the states which can help the rabbit reach state(X).

Hence F(x) = ∑ F(x- jump lengths)

The above recursive equation if used will result in a TLE as X can be up to 10^18. So a faster approach was required.

Matrix Exponentiation by squaring can help solve this problem. This is a very standard problem and many elite coders could solve this problem with many optimizations. For newbies who did get the recursion but could not solve the problem within Time Limit, I suggest to read about how Matrix Exponentiation can be used to solve Fibonacci problem. Refer to this link to know more

 

You can view the solution here:

Problem Setter's solution

Problem Tester's solution

-------------------------------------------------------

STEPAVG (written by Gennady Korotkevitch)

 

There are several different approaches to this problem (and the top contestants always provide a broad range of them).

The simplest of them resulting in a reasonable score is greedy. We'll try to make the set of numbers smaller and closer overall to K at the same time. To do this, take the smallest (X) and the largest (Y) number out of the remaining ones. If K is much smaller than their average (X+Y)/2, then it's reasonable to use two largest numbers for the current operation (as there are. too many large numbers at the moment). If K is much larger than their average, then use two smallest numbers (as there are too many small numbers at the moment). Finally, if K is close to their average (the exact definition of "close" may differ), then use the smallest and the largest number -- this way you replace two numbers which are far from K with one number which is close to K.

A better approach is doing the greedy in the reverse order -- that is, we don't change the given set of numbers (except removing some), but we change K. The idea is taking the smallest (X) and the largest (Y) numbers available again. If K is much smaller than (X+Y)/2, let's say that the last operation is replacing the smallest number and what we get from the remaining numbers with their average. Then it's clear that the number we should get from the remaining ones should be close to 2K-X. Similarly, if K is much larger than (X+Y)/2, then use the largest number in the last operation and try to get as close as possible to 2K-Y with the remaining numbers. Finally, if K is close to (X+Y)/2, then replace X and Y with (X+Y)/2. This kind of approach was successfully implemented by David Stolp (pieguy) for the top spot. I found the solutions of other top scorers less readable, so I'd like to ask them to share their ideas :)

And the last but not the least, I want to apologize for the tie of the top scorers. Actually, their solutions get the smallest possible score -- the differences of their results and K are less than 10^(-6). The reason they didn't get the score of 0.000000 is simple -- there exists a test case where K is less than all of Ai. In fact, making the constraint on N lower would have helped to distinguish them, but it was too late to change anything when I realized that.

 

You can view the solutions here:

Problem Setter's solution

Problem Tester's solution

-------------------------------------------------------

LUCKYDAY (written by Hiroto Sekido)

 

First, we consider the case where X, Y > 0. Let f(i) be the vector (S[i] S[i+1] 1), then there is a 3*3 matrix A such that f(i+1) = A f(i). Now, our task is calculating the number of vectors f(k) = (C m 1) satisfying L[i] <= k <= R[i], and 0 <= m < P.

The sequence f has a period r (at most P^2), since A is a regular matrix. That is f(k+r) = f(k), for all k >= 1.

The first part of solving the problem is calculating a period r and integers k which satisfy f(k) = (C m 1) for each m. Finding minimum k such that f(k+1) = f(1) is enough to calculate a period r. Therefore, we should search P+1 vectors in the sequence f, and it can be calculated by using baby-step-giant-step. At first, calculate the vectors A^d f(1) for 0 <= d < L, and store the vectors. For finding a vector v, we calculate (A^L)^e v for 0 <= e < r/L, and search these vectors in the set of all vectors A^d f(1). The precalculation takes O(L) time, and finding a vector in the sequence takes O(r/L) time if hashes are used for searching. Here, let's set L = P^1.5, then this part takes O(P^1.5) + (P+1) * O(P^2 / P^1.5) = O(P^1.5) time.

The second part is calculating the answer for each intervals. It can be calculated by using binary search. It takes O(Q log P) time.

If X and/or Y are 0, above algorithm cannot be applied, because the matrix A may be singular. However, these cases are not so difficult. A similar method can be used for the case X > 0 or Y > 0, and the problem becomes trivial for the case X = Y = 0.

 

You can view the solution here:

Problem Setter's solution

-------------------------------------------------------

NEWREST (written by Ashar Fuadi)

 

This problem is to be solved using dynamic programming approach plus some combinatorics.

First, define dp[i][j] as the number of ways to cook exactly j different types of dish for i days. As the base case, it is obvious that dp[0][0] = 1, dp[0][x] = 0 for x > 0.

Suppose we know the value of dp[i][j] for some pair (i, j). Now, consider the (i+1)th day. There are two options for us:

  • Cook a dish which has been cooked before. There are j types of such dishes. We can update dp[i+1][j]:
    dp[i+1][j] += j * dp[i][j]
  • Cook a new type of dish. Note that we don't care which type of dish it is; we only care that its type is different from all j types. We can update dp[i+1][j+1]:
    dp[i+1][j+1] += dp[i][j]

After that, we'll take the actual types of dish into account. There are M available types of dish. There are P(M, j) ways to choose j types from M types (the order is important). So, the number of ways to cook exactly j different types of dish for i days is P(M, j) * dp[i][j] = (M! / (M-j)!) * dp[i][j] = M! * (M-j)!-1 * dp[i][j]. Of course, all calculations are performed modulo MOD = 1000000007.

We can precompute all values of k! for all 1 ≤ k ≤ M. The value of k!-1 (mod MOD) can be calculated using Euler's Theorem: k!-1 = k!MOD-2 (mod MOD). Also, the DP values can be computed only once for all T test cases.

Since the original problem asks for the number of ways to cook at most K different types of dish in N days, the final answer is: sum {M! * (M-j)!-1 * dp[N][j]} for all 1 ≤ j ≤ min(M, K).

The complexity of this solution is O(N(M+K) + M log MOD + T(M+K)).

 

You can view the solutions here:

Problem Setter's solution

Problem Tester's solution

-------------------------------------------------------

POSTAL (written by Anirban Mitra)

 

Notice the following 2 observations

1. The postmen can be considered as if they are passing through each other

2. The relative position of a postman never changes

 

Using the first we can calculate the final positions by just adding or subtracting the time from the initial positions depending on the direction being South or North. Combining this with 2, we can easily see that if we sort the final positions, we will get the position of the the respective postman. But we also have to calculate the collisions. For that we can do the sorting of the positions using Bubble Sort where each swapping of adjacent numbers in the array means a collision. And, hence we can easily count the same.

 

You can view the solutions here:

Problem Setter's solution

Problem Tester's solution

-------------------------------------------------------


Comments

  • Login or Register to post a comment.

@Anton Lunyov Your PDF is

_arjun @ 11 Nov 2011 04:36 PM
@Anton Lunyov Your PDF is unreadable

@Hiroto Sekido You still

utkarsh_lath @ 11 Nov 2011 10:04 PM
@Hiroto Sekido You still havent told how to find integers k which satisfy f(k) = (C m 1) for each m

@Hiroto Sekido and why there

jughead @ 11 Nov 2011 10:15 PM
@Hiroto Sekido and why there is no preperiod?

> And the last but not the

tomek @ 11 Nov 2011 11:48 PM
> And the last but not the least, I want to apologize for the tie of the top scorers. It's not a tie if you compute the scores with more precision.

My post got was malformated.

tomek @ 11 Nov 2011 11:49 PM
My post got was malformated. My point was that if you compute the scores more accurately, there is no tie.

@_arjun What do you mean?

anton_adm @ 11 Nov 2011 11:57 PM
@_arjun What do you mean?

@tomek: I know that, but it

gennady_adm @ 12 Nov 2011 12:46 AM
@tomek: I know that, but it seems that at CodeChef 6 digits past decimal point in the score is a must. I could've multiplied the scores by 1000 though.

The challenge problem was a

pieguy @ 12 Nov 2011 01:25 AM
The challenge problem was a really interesting problem, but the constraints were poorly picked. It's very easy to get close to K when N is huge. In local testing, for N=1000 my solution was so close to K that it compared as equal when using doubles for the calculation. But my algorithm does poorly when N is between 30 and 50. Nonetheless, I enjoyed solving it and a 4-way tie isn't bad.

The problem says nothing

tomek @ 12 Nov 2011 01:33 AM
The problem says nothing about rounding scores to 6 digits, I thought that's just an approximation in the UI. The difference between pieguy and me is way below. According to my local testing (on my own data): 1. tomek 2. pieguy 1.7e-205 behind 3. ACRush 1.7e-19 behind 4. Stephen, 1.1e-7 behind.

@utkarsh_lath By using

hiroto_adm @ 12 Nov 2011 02:53 AM
@utkarsh_lath By using baby-step-giant-step, you can find any vector with O(P^0.5) time. (O(p^1.5) time precalculation must be done firstly) At first, search f(1) for calculating period, then search (C 0 1), then search (C 1 1), ..., then search (C P-1 1). @jughead Because A is non-singular, f(k-1) can be determined uniquely from f(k), that is f(k-1) = A^(-1) f(k). If the sequence f has a preperiod, for instance let the sequence be f(1) f(2) f(3) f(4) f(5) f(3) f(4) f(5) f(3)..., it must be hold that f(2) = f(5) = A^(-1) f(3) and f(1) = f(4).

I admit to solving Lucky Days

tomek @ 12 Nov 2011 02:58 AM
I admit to solving Lucky Days in brute-forcey O(P^2) :) Domino was fun.

@tomek: interesting

pieguy @ 12 Nov 2011 04:06 AM
@tomek: interesting breakdown. Did you test all submissions or just the fastest? For example my third submission ( http://www.codechef.com/viewsolution/723238 ) should score better than my fourth ( http://www.codechef.com/viewsolution/727102 ), but the "view solution" link goes to my fourth. By the way the 6 digit thing is due to something called the "Master Judge" which reads the scores from the individual test files and averages them, so that's why the challenge problem always takes the average over all test files.

@pieguy: You're right, I only

tomek @ 12 Nov 2011 04:19 AM
@pieguy: You're right, I only tested the solution that the system is showing on the problem site. Your third submission is indeed best on my data and is only 1e-281 behind.

I ran again on all

tomek @ 12 Nov 2011 05:06 AM
I ran again on all submissions. I have 500 random cases. Here are the corrected scores: 1. tomek 2. pieguy 1.0e-281 3. ACRush 1.2e-267 4. triplem 9.4e-8.

Those aren't entirely

triplem @ 12 Nov 2011 06:12 AM
Those aren't entirely accurate since I stopped submitting about a week ago as soon as I equalled pieguy's score, though I doubt I'd have beaten your scores with more time anyway :)

@Hiroto Sekido ok, i see. But

jughead @ 12 Nov 2011 11:33 AM
@Hiroto Sekido ok, i see. But i think matrix can be singular if Y = 0 and this case we should proceed separately, am i right?

Codechef why don't you

ambujpandey @ 12 Nov 2011 12:41 PM
Codechef why don't you release all the test cases and their answers after the contest is over. Because we'll never be able to know what was wrong with OUR approach. I've faced this many times. All of the Topcoder, Codeforces etc. do it. You surely can come up with a mechanism that when we submit a solution to a problem in Practice Section, it gives report that your solution failed on so and so test case. Please look into it.

@anton_adm sorry, I think it

_arjun @ 12 Nov 2011 12:41 PM
@anton_adm sorry, I think it was a problem on chrome only, actually the words are concatenated with each other, although it is openning fine of moziala. Thanks

Why would a O(P^1.5) soln for

pragrame @ 12 Nov 2011 11:33 PM
Why would a O(P^1.5) soln for luckdays take (about) as long as the O(P^2) solns. I had a little trouble getting my O(P^1.5) luckyday soln to pass time even. And I'm curious to know what approach did people who solved it in <10 s use.

And also, no graph related

ambujpandey @ 13 Nov 2011 12:39 AM
And also, no graph related problem in the past three months!

My luckyday solution was O(P

triplem @ 13 Nov 2011 01:58 AM
My luckyday solution was O(P + Q log P). There are several special cases, but the basic idea is that after at most P elements in the sequence, you end up with consecutive elements being kA and kB. The next part of the sequence is then k times the first part, then the next part is k^2 times the first part, etc. You can thus calculate all solutions just based on the first P elements and inverses of k^i.

Thanks triplem. I'll look

pragrame @ 13 Nov 2011 01:28 PM
Thanks triplem. I'll look into the special cases... but is there any intuition why there'd be consecutive terms multiplied by k? (As in, is there an intuition why this could happen in a general situation? Like we'd know that the sequence would repeat after atmost 'n' terms if there are atmost 'n' distinct states - in general)

btw i had a special case in

mmaxio @ 13 Nov 2011 04:32 PM
btw i had a special case in my solution for "Lucky Days" when x+y = 1(mod p).

There are only P possible

triplem @ 14 Nov 2011 01:31 AM
There are only P possible values for the ratio of consecutive terms to take, so you must get a repeat somewhere. PS - forgot to mention, my earlier comment only applies when Z = 0. You can translate the sequence so Z becomes 0 in most cases, though that is where the special cases come in (including X+Y==1 mod P).

Cool. So hypothetically, if I

pragrame @ 14 Nov 2011 04:04 PM
Cool. So hypothetically, if I had my sequence defined by S(i) = xS(i-1) + yS(i-2) + zS(i-3) + t, i could precompute in O(P^2) after translating t to 0, rite? {cuz of 2 possible values of ratios S(i):S(i-1) and S(i-1):S(i-2)... after which we'd be handling something like kS(2), kS(1), kS(0)}

@ambujpandey: We are not yet

admin @ 14 Nov 2011 05:22 PM

@ambujpandey: We are not yet convinced that giving away test data is a good idea. We used to do that before but have stopped doing it sometime back. We believe that once the test data is out, people may not try "that hard" to get their solution working. To save someone being completely lost we have started the process of publishing editorials at the end of each contest and provided a forum to ask questions to the problem setters directly as well as other members in the community.

Just a note: For the new

rosyish @ 16 Nov 2011 03:01 PM
Just a note: For the new restaurant problem, a simple recurrence also exists. dp(i,j) = j*dp(i-1,j) + (M-j+1)*dp(i-1,j-1) . As there are 100 cases, this approach will time out, hence we need to have a preprocessed dp.
CodeChef is a non-commercial competitive programming community
  • About CodeChef
  • About Directi
  • CEO's Corner
  • C-Programming
  • Programming Languages
  • Contact Us
© 2009 Directi Group. All Rights Reserved. CodeChef uses SPOJ © by Sphere Research Labs
In order to report copyright violations of any kind, send in an email to copyright@codechef.com
CodeChef a product of Directi
The time now is:
CodeChef - A Platform for Aspiring Programmers

CodeChef was created as a platform to help programmers make it big in the world of algorithms, computer programming and programming contests. At CodeChef we work hard to revive the geek in you by hosting a programming contest at the start of the month and another smaller programming challenge in the middle of the month. We also aim to have training sessions and discussions related to algorithms, binary search, technicalities like array size and the likes. Apart from providing a platform for programming competitions, CodeChef also has various algorithm tutorials and forum discussions to help those who are new to the world of computer programming.

Practice Section - A Place to hone your 'Computer Programming Skills'

Try your hand at one of our many practice problems and submit your solution in a language of your choice. Our programming contest judge accepts solutions in over 35+ programming languages. Preparing for coding contests were never this much fun! Receive points, and move up through the CodeChef ranks. Use our practice section to better prepare yourself for the multiple programming challenges that take place through-out the month on CodeChef.

Compete - Monthly Programming Contests and Cook-offs

Here is where you can show off your computer programming skills. Take part in our 10 day long monthly coding contest and the shorter format Cook-off coding contest. Put yourself up for recognition and win great prizes. Our programming contests have prizes worth up to Rs.20,000 and $700lots more CodeChef goodies up for grabs.

Discuss

Are you new to computer programming? Do you need help with algorithms? Then be a part of CodeChef's Forums and interact with all our programmers - they love helping out other programmers and sharing their ideas. Have discussions around binary search, array size, branch-and-bound, Dijkstra's algorithm, Encryption algorithm and more by visiting the CodeChef Forums and Wiki section.

CodeChef Community

As part of our Educational initiative, we give institutes the opportunity to associate with CodeChef in the form of Campus Chapters. Hosting online programming competitions is not the only feature on CodeChef. You can also host a coding contest for your institute on CodeChef, organize an algorithm event and be a guest author on our blog.

Go For Gold

The Go for Gold Initiative was launched about a year after CodeChef was incepted, to help prepare Indian students for the ACM ICPC World Finals competition. In the run up to the ACM ICPC competition, the Go for Gold initiative uses CodeChef as a platform to train students for the ACM ICPC competition via multiple warm up contests. As an added incentive the Go for Gold initiative is also offering over Rs.8 lacs to the Indian team that beats the 29th position at the ACM ICPC world finals. Find out more about the Go for Gold and the ACM ICPC competition here.

Domain Name Registration, Web hosting, and Website Design provided by BigRock.com