Ranking (as of 2014-09-30): 30 out of 599
Language: C++
/*
UVa 10564 - Paths through the Hourglass
To build using Visual Studio 2012:
cl -EHsc -O2 UVa_10564_Paths_through_the_Hourglass.cpp
*/
#include <cstdio>
#include <cstring>
/*
Let cells[r][c] is the value of cell at r-th row, c-th column, and,
nr_paths[r][c][s] is the number of paths that leads to cells[r][c] with
the path value of s, then:
nr_paths[r][c][s] = nr_paths[r - 1][left to c][s - cells[r][c]] +
nr_paths[r - 1][right to c][s - cells[r][c]
*/
const int N_max = 20, S_max = 500;
int cells[N_max * 2 - 1][N_max];
long long nr_paths[N_max * 2 - 1][N_max][S_max];
#ifdef DEBUG
void print_s(int N, int S, int r)
{
printf("%d\n", r);
for (int c = 0; c < N; c++)
for (int s = 0; s <= S; s++)
printf("%3lld%c", nr_paths[r][c][s], ((s < S) ? ' ' : '\n'));
putchar('\n');
}
#endif
/*
6 41 r cs
6 7 2 3 6 8 0 0
1 8 0 7 1 1 1
2 6 5 7 2 2
3 1 0 3 3
7 6 4 4
8 5 5
8 8 6 4
6 5 3 7 3
9 5 9 5 8 2
6 4 4 1 3 9 1
2 6 9 4 3 8 10 0
*/
void follow_paths(int N, int S)
{
for (int c = 0; c < N; c++)
for (int s = 0; s <= S; s++)
nr_paths[2 * (N - 1)][c][s] = (s == cells[2 * (N - 1)][c]) ? 1 : 0;
#ifdef DEBUG
print_s(N, S, 2 * (N - 1));
#endif
for (int r = 2 * (N - 1) - 1, ci = 1; r >= 0; r--, ((r >= N - 1) ? ci++ : ci--)) {
for (int c = ci; c < N; c++) {
int cs = cells[r][c];
for (int s = 0; s <= S; s++) {
if (s < cs)
nr_paths[r][c][s] = 0;
else {
long long np_left, np_right;
if (r >= N - 1) {
np_left = nr_paths[r + 1][c - 1][s - cs]; // from lower left
np_right = nr_paths[r + 1][c][s - cs]; // from lower right
}
else {
np_left = (c > ci) ? nr_paths[r + 1][c][s - cs] : 0;
// from lower left
np_right = (c < N - 1) ? nr_paths[r + 1][c + 1][s - cs] : 0;
// from lower right
}
nr_paths[r][c][s] = np_left + np_right;
}
}
}
#ifdef DEBUG
print_s(N, S, r);
#endif
}
}
void trace_path(int N, int r, int c, int s, char* path)
{
int cs;
if (r < N - 1) {
cs = cells[r][c];
if (c > r && nr_paths[r + 1][c][s - cs]) { // to lower left
path[r] = 'L';
trace_path(N, r + 1, c, s - cs, path);
}
else { // to lower right
path[r] = 'R';
trace_path(N, r + 1, c + 1, s - cs, path);
}
}
else if (r < 2 * (N - 1)) {
cs = cells[r][c];
if (nr_paths[r + 1][c - 1][s - cs]) { // to lower left
path[r] = 'L';
trace_path(N, r + 1, c - 1, s - cs, path);
}
else { // to lower right
path[r] = 'R';
trace_path(N, r + 1, c, s - cs, path);
}
}
}
int main()
{
while (true) {
int N, S;
scanf("%d %d", &N, &S);
if (!N && !S)
break;
for (int r = 0, ci = 0; r < 2 * N - 1; r++, ((r < N) ? ci++ : ci--))
for (int c = ci; c < N; c++)
scanf("%d", &cells[r][c]);
follow_paths(N, S);
int first_c = -1;
long long nr = 0;
for (int c = 0; c < N; c++)
if (nr_paths[0][c][S]) {
if (first_c == -1)
first_c = c;
nr += nr_paths[0][c][S];
}
printf("%lld\n", nr);
if (first_c != -1) {
char path[N_max * 2 - 1];
trace_path(N, 0, first_c, S, path);
path[2 * (N - 1)] = '\0';
printf("%d %s\n", first_c, path);
}
else
putchar('\n');
}
return 0;
}