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 » December 2011 Contest Problem Editorials

December 2011 Contest Problem Editorials

 

Problem Tester for the December 2011 Contest was David Stolp.

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

MOVES (written by AnhDQ)


Suppose that the robot always takes the "right" move at first. We could easily see that a way of robot reaching cell (N, N) is just a set of cells in which the robot takes "turns". This set is chosen by selecting a combination of K/2 column indices and (K-1)/2 row indices among N-2 indices each dimension. It is easily computed by formula C(K/2, N-2) * C((K-1)/2, N-2). At last, we double the result of this formula to get the last result (because the table is a square one so it is totally the same in case the robot takes the "down" move at first).

 

The last problem is compute the Combination formula as fast as possible. In this case we have to compute the result modulo 1,000,000,007 which is a prime, so we just use a power function to fast compute that (in logarithmic time).

 

You can view the solution here:

Problem Setter's solution

Problem Tester's solution

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

STREGGS (written by Hiroto Sekido)

 

You can view the editorial for this problem here.

 

You can view the solution here:

Problem Setter's solution

Problem Tester's solution

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

CHEFGIFT (written by Vamsi Kavala)

 

You can view the editorial for this problem here.

 

You can view the solutions here:

Problem Setter's solution

Problem Tester's solution

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

SPIN (written by Gennady Korotkevich)

 

The easiest way to get accepted is to output a sequence of 100 random moves for N = 2 and -1 for all other cases. Not that it really matters :)

 

One of the simplest good approaches is the following. Let's fix color C into which we're going to color all the wheels. Let's say that a wheel is reachable from C if it can be colored into C through a sequence of moves each of which rotates a wheel of color C. It's easy to check this for all wheels in O(NM) total time. Let's rotate some random wheel from those which are not reachable from C several times until all of the wheels are reachable. When this finally happens, let's rotate some random wheel of color C so that at least one of the wheels is colored into C at the first iteration. It can be seen that we'll actually color all the wheels into C pretty quickly. This approach is enough to get a score of under 450.

 

Other solutions should probably use a similar idea. Tiancheng Lou's solution receiving a score of under 303 also makes use of beam search, as it can be inferred from his code.

 

You can view the solution here:

Problem Setter's solution

Problem Tester's solution

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

SHORT2 (written by Gennady Korotkevich)

 

You can view the editorials for this problem here.

 

You can view the solutions here:

Problem Setter's solution

Problem Tester's solution

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

HYPER (written by Gennady Korotkevich)

 

CodeChef contests are always great for learning and competing. A set of 5 algorithm problems of different difficulty levels, a challenge problem for separating those who solved the same number of problems. The thing which seems to be a bit odd about this is that the winner is always determined by the challenge problem, as most top coders are able to solve a set of any 5 problems given 10 days. I tried to set a couple of really hard problems this month for a change. And yes -- there were only 10 accepted solutions to them in total, so my goal was achieved :) Anyway, it won't probably be a trend -- such hard problems are always difficult to come up with.

 

Let's move on to the solution. For a start, let f(N,M) be the number of hypertrees on N vertices and M edges.

 

Suppose we've fixed a particular edge of a hypertree. What will happen if we remove it? The correct answer is: the hypertree will break down into two or three components. The rest of the solution may seem easy. We can try every possible way of distribution of the vertices between (or among) the components and also every possible way of distribution of edges. So, if we've got a way to break it down into components (this means (vertices, edges)) (N1,M1), (N2,M2), (N3,M3) such that N1+N2+N3 = N and M1+M2+M3 = M, then do the following: f(N,M) += f(N1,M1)*f(N2,M2)*f(N3,M3). The same applies when there are only two components. As we try every possible starting edge, we should finally divide f(N,M) by M.

 

To see why this is wrong, consider an example. Suppose there are just 5 vertices. First, we take an edge (1,2,3) to separate the hypertree into components (1,2,4,5) and (3). Then, in (1,2,4,5) component we take an edge (1,2,4) to separate the hypertree into components (1) and (2,4,5). Then, in (2,4,5) component we finally take an edge (2,4,5) to separate the hypertree into components (2), (4) and (5). Everything seems correct, but... notice that (1,2,4) can actually be removed! This happened because after (1,2,3) separated the hypertree into (1,2,4,5) and (3), vertices 1 and 2 remained connected through an already processed edge, and we should have remembered about that, as edge (1,2,4) couldn't just separate (1) from (2,4,5) now.

 

In general, if we look at the connected pairs induced by the processed edges, they'll form some connected components of vertices which we'll call bunches (not to mix them up with the components of the hypertree). As the actual indices of the vertices don't matter, it'll be enough if we just have a set (or, in fact, multiset) of sizes of the bunches. The recurrence turns into f(A,M), where A is the aforementioned set. The starting set is thus (1,1,...,1) (consisting of N 1's). In the example above, the starting set is (1,1,1,1,1), and after the first edge it becomes (2,1,1).

 

These induced connections, of course, bring some problems to deal with. The easy case now is when removing an edge results in just two components. There should be no edges between the components (so every bunch should go to either side as a whole), otherwise the initial edge can be removed. If the two vertices of the initial edge which go to the same component are from different bunches, these bunches should become connected now. We can find the answer recursively for the resulting sets and then merge these answers to recalculate our DP.

 

When removing an edge results in three components, some induced connections may be split between the components. Still all three components shouldn't be connected by them, otherwise the initial edge can be removed again. Then, we should connect all bunches if they are connected by the initial edge. Even more, before starting to search for the answer for the first component, we should connect all the bunches from the second and the third component (and similarly for the other components) -- otherwise it may so happen that a pair of bunches becomes connected in both the first and the second components, so an edge in either of them can be removed. Only after all these things, we can finally move on to the smaller sets :)

 

This part should also be optimized, as 3^17 * 17^4 is a bit too much (of course it's not too much in case you have a lot of time). The key is to notice that the bunches of the same size are indistinguishable, so we don't need to try every possible distribution of them. My solution which has this optimization works for about a minute for N = 17 and it works for several hours without it. It should probably work even faster if the distributions are generated using recursion.

 

Note that a more understandable edition of my code has been uploaded :)

 

David Stolp, who was the tester this time, used a different approach (in my opinion, it's even simpler to understand). Here is his description:

 

I define a biconnected hypertree as one with no articulation points. Then I define biconnected components in the usual fashion. My algorithm has 2 stages. First I count the number of biconnected hypertrees (this is rather slow), then use those values to compute the total number of hypertrees (this is quite fast).

 

Consider a biconnected hypertree. Consider any edge of this hypertree, and count the number of hyperedges each of its 3 vertices belongs to. How many of the vertices belong to exactly 1 hyperedge? It can't be 0 because then it wouldn't be a hypertee. It can't be 2 because then it wouldn't be biconnected. If it's 3, then the hypertree consists of only a single hyperedge. That leaves 1.

 

Now remove from each hyperedge the vertex that appears only once. This turns the hypergraph into a plain graph, and this graph must be biconnected. Thus, my first step is to count the number of biconnected graphs with n vertices and m edges for n+m<=17. This is where most of my execution time is because I don't bother to memoize. Some combinatorics gets me the total number of biconnected hypertrees. Then I brute force all configurations of biconnected components in a hypertree (using memoization this time to speed things up).

 

David's solution actually works several times faster than mine. It also made me believe that the problem was easier than I had previously thought, but it still proved to be very hard :)

 

You can view the solutions here:

Problem Setter's solution

Problem Tester's solution

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


Comments

  • Login or Register to post a comment.

please any body share

dabbcomputers @ 11 Dec 2011 05:24 PM
please any body share algorithm for fast computing pascal triangle.... ?

For CHEFGIFT: will this

pkvprakash_86 @ 11 Dec 2011 09:16 PM
For CHEFGIFT: will this solution work? http://www.codechef.com/viewsolution/748823

thanks:) problems were very

abdukodir @ 11 Dec 2011 09:55 PM
thanks:) problems were very interesting! Unfortunately I could solve only two of them

This problemset is nice and

hacker007 @ 11 Dec 2011 10:58 PM
This problemset is nice and challenging. CodeChef is getting better and better. Keep up the great work, Chef. I like the editorial too, and hopefully HYPER would be available ASAP. Big thanks to the writers, tester, and admins.

One of the way to speed up

rajneesh2k10 @ 11 Dec 2011 11:44 PM
One of the way to speed up your computation of pascal triangle is to replace '%' operation by a '-' operation, which lead to acceptance of solution of problem MOVES by pre-computing pascal triangle. :)

i tried to read the problem

cyberax @ 12 Dec 2011 12:52 AM
i tried to read the problem setter's solution for the HYPER problem. well, 5 seconds actually. the time for me to realize that : - almost every variable was "sz", or "ff", or "rh", or something that nobody won't understand ; - there is absolutely no comment anywhere on the way of the solution (the one we don't know yet) is *implemented* ; - the whole code is packed into a unique ugly fonction "solve", that does we-dont-know-what. i hoped that reading the code would have helped me to enlight the way of doing this, actually it makes it even more misunderstandable. thx.

omg i finally get it NOW..the

foofoo @ 12 Dec 2011 01:14 AM
omg i finally get it NOW..the egg problem..after 10 days..hilarious!

O(n^2*k*T) solution for

pratikmoona @ 12 Dec 2011 07:39 AM
O(n^2*k*T) solution for STREGGS? n^2 * k * T is greater than the dreaded 10^9 number (usually the worst case upper limit for any complexity of an algorithm in sports programming is of the order of 10^8 or lesser). I think an O(n*k*log(n)) solution is also possible using interval trees.

how we can replace % with

dabbcomputers @ 12 Dec 2011 02:57 PM
how we can replace % with '-'....?? i used my own mod function to reduce complxity.... ie (x-(x/n)*n)

All the test cases cannot be

javadecoder @ 12 Dec 2011 04:32 PM
All the test cases cannot be worst cases,also K<=N ,so it is in order of 10^8,that is why 8s time limit...

@dabbcomputers: Since the

javadecoder @ 12 Dec 2011 04:35 PM
@dabbcomputers: Since the computation of pascal triangle involves only the ADDITION of previously computed results,you can rewrite the expression: C[n][r]=(C[n-1][r]+C[n-1][r-1])%mod -----------> C[n][r]=C[n-1][r]+C[n-1][r-1] ,if(C[n][r]>=mod) C[n][r]-=mod This way the computation will be much faster,as it does not involve modulus operation.

@dabbcomputers: "i used my

cyberax @ 12 Dec 2011 04:39 PM
@dabbcomputers: "i used my own mod function to reduce complxity.... ie (x-(x/n)*n)" actually you increased complexity of certain cases (powers of 2). you should let your compiler do the optimization tricks for you. http://en.wikipedia.org/wiki/Modulo_operation#Performance_issues

@Javadecoder: Well, actually,

pratikmoona @ 12 Dec 2011 08:10 PM
@Javadecoder: Well, actually, usually there is one file which contains the worst case input for all the test cases...

I tried but I could not

svm11 @ 13 Dec 2011 11:58 AM
I tried but I could not decipher the heuristic used by ACRush to distinguish between promising and non-promising states. Can any one throw some light on this. Thnx in advance :-)

@cyberax: I've had no time to

gennady_adm @ 13 Dec 2011 07:39 PM
@cyberax: I've had no time to refactor my code for HYPER lately. I've already sent the editorial along with a more understandable code to the admins, so it should get posted soon.

@gennady_adm: nice, thank

cyberax @ 14 Dec 2011 04:10 AM
@gennady_adm: nice, thank you. on the other hand, your new code gives me a std::bad_alloc. something special i need to do to make it work ? anyway. i'll be looking at the tester's solution. but it remains something i don't understand. "Consider a biconnected hypertree. Consider any edge of this hypertree, and count the number of hyperedges each vertex belongs to. How many of the vertices belong to exactly 1 hyperedge? It can't be 0 because then it wouldn't be a hypertee. It can't be 2 because then it wouldn't be biconnected. If it's 3, then the hypertree consists of only a single hyperedge." {(1,2,3),(1,2,4),(1,2,5)} was an example given for N = 5. there are 3 vertices that belong to only one hyperedge (3, 4 and 5 precisely), but the hypertree doesn't consist in a single hyperedge. there are 3 hyperedges actually. did i miss something obvious ? moreover, there could be more than 3. for instance : for N=7, consider {(1,2,3),(1,2,4),(1,2,5),(3,6,7)}. there are 4 vertices that belong to only one hyperedge (4, 5, 6, and 7). i'm really stuck.

@cyberax: It's looks at only

david_adm @ 14 Dec 2011 05:25 AM
@cyberax: It's looks at only one hyperedge at a time, and for the 3 vertices belonging to this hyperedge, counts the number of hyperedges in the entire hypertree that each vertex belongs to. Also, your {(1,2,3),(1,2,4),(1,2,5),(3,6,7)} example is not biconnected (3 is an articulation point). The biconnected components are {(1,2,3),(1,2,4),(1,2,5)} and {(3,6,7)}. For your other example {(1,2,3),(1,2,4),(1,2,5)}, in the hyperedge (1,2,3) only (3) belongs to exactly one hyperedge.

In short 2, how is the

loOc @ 14 Dec 2011 08:57 AM
In short 2, how is the problem of solving (a+p)(b+p)%ab same as ab%(a-p)(b-p). How can I prove this? (Doesn't seems obvious to me!)

@loOc: Simply replace a with

pratikmoona @ 14 Dec 2011 04:22 PM
@loOc: Simply replace a with a - p and b with b - p.

@david_adm: thank you ! i now

cyberax @ 14 Dec 2011 05:41 PM
@david_adm: thank you ! i now understand this a bit more.

@gennady_adm: It seems that

hacker007 @ 14 Dec 2011 11:11 PM
@gennady_adm: It seems that your solution to HYPER got WA. Please check it out.

@cyberax, hacker007: It works

gennady_adm @ 15 Dec 2011 12:32 AM
@cyberax, hacker007: It works fine for me. The only difference is that the input should consist of just one integer N. Moreover, if I modify it a little bit so that it works for multiple test cases, it will get TL for sure. The only way seems to be pasting the answers directly into the source code -- just like David did in his solution.

@gennady_adm: You're right.

hacker007 @ 15 Dec 2011 08:29 PM
@gennady_adm: You're right. Thanks for the explanation.

Gennady, I really enjoyed

gawry @ 15 Dec 2011 11:09 PM
Gennady, I really enjoyed your tasks! It would be awesome to get one-two really difficult problems each month :)
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