http://acm.pku.edu.cn/JudgeOnline/problem?id=1124
Код:
#include <stdio.h>
#define UP 1
#define DOWN 2
#define RIGHT 3
#define LEFT 4
#define MAX_PATHS 50000
int rows;
int columns;
char map[25][25];
double loads[25][25];
char inputline[100];
int doorx[30];
int doory[30];
int start;
int finish;
int load;
int paths[MAX_PATHS][100];
int current_path[500];
int travelled[25][25];
int num_paths;
int min_path;
void copy_path(int steps, int number)
{
int x;
if (number > MAX_PATHS)
{
num_paths++;
return;
printf("Resetting the minimum to %d\n", min_path);
num_paths = 0;
min_path = min_path - 1;
return;
}
for (x = 0; x < steps; x++)
{
paths[number][x] = current_path[x];
//printf("Copying path %d step %d value %d\n", number, x, current_path[x]);
}
num_paths = number + 1;
}
void check_path(int sx, int sy, int fx, int fy, int step)
{
if ((sx == fx) && (sy == fy))
{
//printf("Found path %d %d %d %d %d %d\n", sx, sy, fx, fy, step, num_paths);
if (step < min_path)
{
min_path = step;
copy_path(step, 0);
}
else if (step == min_path) copy_path(step, num_paths);
return;
}
// If I have been here, it is not a sidewalk, I have reached the minimum path, or it is not a valid space return
if (travelled[sx][sy] != 0) return;
if ((map[sx][sy] != '.') && (step != 0)) return;
if (step >= min_path) return;
if ((sx < 0) || (sy < 0) || (sx == rows) || (sy == columns)) return;
travelled[sx][sy] = step;
if (sx < fx)
{ /* check down then up */
current_path[step] = DOWN;
check_path(sx+1, sy, fx, fy, step + 1);
current_path[step] = UP;
check_path(sx-1, sy, fx, fy, step + 1);
}
else
{ /* check down then up */
current_path[step] = UP;
check_path(sx-1, sy, fx, fy, step + 1);
current_path[step] = DOWN;
check_path(sx+1, sy, fx, fy, step + 1);
}
if (sy < fy)
{
current_path[step] = RIGHT;
check_path(sx, sy+1, fx, fy, step + 1);
current_path[step] = LEFT;
check_path(sx, sy-1, fx, fy, step + 1);
}
else
{
current_path[step] = LEFT;
check_path(sx, sy-1, fx, fy, step + 1);
current_path[step] = RIGHT;
check_path(sx, sy+1, fx, fy, step + 1);
}
travelled[sx][sy] = 0;
return;
}
void add_paths(int x, int y, int fx, int fy, double per)
{
int cx, cy;
int i, j;
if (num_paths > MAX_PATHS)
{
printf("Ran out of space %d %d %d %d %d\n", x, y, fx, fy, num_paths);
return;
}
//printf("Adding paths %d %d %d %d %lf\n", x, y, num_paths, min_path, per);
for (j = 0; j < num_paths; j++)
{
cx = x; cy = y;
for (i = 0; i < (min_path-1); i++)
{
//printf("Adding to %d %d value %lf\n", cx, cy, per);
switch (paths[j][i])
{
case UP: cx = cx-1; break;
case DOWN: cx = cx+1; break;
case RIGHT: cy = cy+1; break;
case LEFT: cy = cy-1; break;
}
loads[cx][cy] += per;
}
}
}
void add_load(int s, int f, int l)
{
int x, y;
int myx, myy;
int fx, fy;
double per;
//printf("Adding load %d %d %d\n", s,f,l);
num_paths = 0;
min_path = 60;
for (x = 0; x < rows; x++)
for (y = 0; y < columns; y++)
travelled[x][y] = 0;
myx = doorx[s];
myy = doory[s];
fx = doorx[f];
fy = doory[f];
//printf("Path search for %d %d to %d %d\n", myx, myy, fx, fy);
check_path(myx, myy, fx, fy, 0);
per = (double)load / num_paths;
add_paths(myx, myy, fx, fy, per);
// printf("Adding load from %d %d to %d %d of size %d %lf %d\n", myx, myy, fx, fy, l, per, num_paths);
}
void print_loads(void)
{
int x, y;
for (x = 0; x < rows; x++)
{
for (y = 0; y < columns; y++)
{
printf("%7.2lf", loads[x][y]);
}
printf("\n");
}
}
int main(void){
int x,y;
gets(inputline);
sscanf(inputline, "%d %d", &columns, &rows);
for (x = 0; x < rows; x++)
{
gets(inputline);
for (y = 0; y < columns; y++)
{
loads[x][y] = 0;
map[x][y] = inputline[y];
if ((inputline[y] != '.') && (inputline[y] != 'X'))
{
doorx[inputline[y] - 'A'] = x;
doory[inputline[y] - 'A'] = y;
}
}
}
#if 0
for (x = 0; x < rows; x++)
{
for (y = 0; y < columns; y++)
{
printf("%7.2lf", loads[x][y]);
}
printf("\n");
}
for (x = 0; x < rows; x++)
{
for (y = 0; y < columns; y++)
{
printf("%c", map[x][y]);
}
printf("\n");
}
#endif
gets(inputline);
while (inputline[0] != 'X')
{
sscanf(&(inputline[2]), "%d",&load);
start = inputline[0]-'A';
finish = inputline[1]-'A';
add_load(start, finish, load);
gets(inputline);
}
print_loads();
}