Problem B
Time Limit:1000MS Memory Limit:65536K
Total Submit:220 Accepted:67
Description
code4101听说这次选拔赛要他出3道题,吓得哭晕在厕所里一整天。第二天他早早的就去图书馆,废寝忘食(早餐午餐都没吃)的出题,晚上终于完成了。
现在他决定犒劳自己,去校内的两个食堂各吃一顿晚餐。
已知学校是个10*10的网格,code4101当前所在位置是A,他每次能从当前格移动到上下左右4格中的任意一格,学校内共有六个食堂,编号1,2,...,6。
code4101是路痴,不知道先去哪个食堂再去哪个食堂,使得总路程最短,所以只好请你来带路。
Input
输入数据的第一行为一个整数T,表示有T(0 < T < 20)组测试数据。
每个测试有10行,每行10个字符。字符’A’是起点,’1’~’6’代表6个食堂所在位置。除了’#’代表不能行走的障碍点,’.’等字符所在格子都是可以行走的通路。
每两个测试间会有一个空行。输入数据保证不会出现文中未提到的字符,且解一定存在。
Output
每个测试数据在一行输出一个数字,代表最小的总移动次数。
Sample Input
2
.......#12
..#....#.#
..##...A#.
.........#
...###....
..#.#..4..
.......#..
.5#.#.....
......3...
...6......
A......#..
..#......#
..##..1...
.........#
...###....
..#2#..4..
.......#..
.5#.#.....
......3...
...6......
Sample Output
7
12
思路:先找出A到各个食堂的最短路径,再找出食堂与食堂之间的最短路,求两者和的最小值,借助BFS(广度优先搜索完成)(ps:因为c没有内置的队列,所以自己用数组来模拟)(代码写的有点丑陋)
#include<stdio.h>
#include<math.h>
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int bfs(char grid[10][10],int x,int y,int p,int q) {
int queue[100][2];
int left=0,right=1;
int dis=0;
int i;
int nx,ny;
int size;
int vis[10][10]={0};
queue[0][0]=x;
queue[0][1]=y;
while(left < right) {
size = right;
for(; left<size; left++) {
int px = queue[left][0];
int py = queue[left][1];
if(px==p && py==q){
return dis;
}
for(i=0; i<4; i++) {
nx = px + dir[i][0];
ny = py + dir[i][1];
if(nx>=0 && nx<10 && ny>=0 && ny<10 && grid[nx][ny]!='#' && !vis[nx][ny]) {
queue[right][0] = nx;
queue[right][1] = ny;
right++;
vis[nx][ny] = 1;
}
}
}
dis+=1;
}
return -1;
}
void demo() {
int i,j;
int x,y;
int dis=2147483647;
int min;
char grid[10][10];
int dis1[6]={0};
int dis2[6][5]={0};
int pos[6][2];
int k=0;
for(i=0; i<10; i++){
for(j=0; j<10; j++){
scanf("%c",&grid[i][j]);
if(grid[i][j] == 'A'){
x = i;
y = j;
}
if(grid[i][j] !='.' && grid[i][j] != '#' && grid[i][j] != 'A'){
pos[k][0] = i;
pos[k][1] = j;
k++;
}
}
getchar();
}
for(i=0; i<6; i++) {
dis1[i] = bfs(grid,x,y,pos[i][0],pos[i][1]);
}
for(i=0; i<6; i++) {
k=0;
for(j=0; j<6; j++) {
if(i==j){continue;}
dis2[i][k] = bfs(grid,pos[i][0],pos[i][1],pos[j][0],pos[j][1]);
k++;
}
}
for(i=0; i<6; i++) {
if(dis1[i]==-1){continue;}
min = 2147483647;
for(j=0; j<5; j++) {
if(dis2[i][j]==-1){continue;}
min = fmin(min,dis1[i]+dis2[i][j]);
}
dis = fmin(dis,min);
}
printf("%d\n",dis);
getchar();
}
void main() {
int n;
scanf("%d",&n);
getchar();
while(n--){
demo();
}
}