UVa 10506 - The Ouroboros problem

10506 - The Ouroborus Problem

 * http://acm.uva.es/p/v105/10506.html

Summary
Input is a base(b) and a length(s). From this, one can enumerate all numbers of exactly length s, each character being in the range of 0 to b-1. Thus for b=3 and s=2, all numbers are 00,01,02,10,11,12,20,21,22. The goal is to take these numbers and squeeze them into a sequence where any s consecutive numbers (including wrap-around from the end back to the beginning) is one of the numbers in your list. For example in the sequence 021201, the numbers of length 4 are 0212,2120,1201 and the wrap-arounds 2010,0102,1021. However each number must appear exactly once in this fashion. See the Sample Input/Output for a full solution to a couple examples.

Explanation
One of the easier to see solutions is that one can write down each number as a vertex in a graph, then draw b directed edges out of each number into the number it would become, for example with b=3 and s=4, given the number 0121, the '0' edge would turn that into 1210, '1' -> 1211, '2' -> 1212. This representation is calling for a Hamiltonian Cycle, thus to find the sequence of numbers is very slow (the strong condition doesn't necessarily hold), however a brute force guess and check DFS solution will be accepted on UVA.

Gotchas
Note that just because your solution may not agree exactly with the sample output does not mean your output is incorrect. Because of the wrapping, one can start at any place in the sequence. Also any sequence can be reversed. Thus UVA has an alternate checker for this program, any correct sequence is valid. You can even code your own checker for this problem.

Optimizations
The nice solution to this problem is seeing that it can be represented as an Eulerian Cycle. Instead of each vertex representing the a full number of length s, instead each vertex can represent the substring of length s-1. In the Hamiltonian view, the first number of a vertex has no influence on which numbers it can transform into and there are $$b^s$$ (no pun intended!) vertices, each vertex having an in-degree of b and an out-degree of b, however each vertex is only allowed to be visited once. In the Eulerian view, we have $$b^{(s-1)}$$ vertices, each vertex with an in-degree and an out-degree of b still, but each vertex must be visited b times now. All one needs now is a smart way to choose the next edge from each vertex as a function of how many times that vertex was chosen previously such that one doesn't arrive at a vertex with no more edges to traverse while some numbers haven't been printed out.

Input
Same Input as on UVA 3 3 4 2

Output
Same Output as on UVA 000111222121102202101201002 1111000010100110