厦门理工oj 1145 Problem B (广度搜索)

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();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值