AOJ-AHU-OJ-579 期末考试之考试传纸条

37 篇文章 0 订阅
22 篇文章 0 订阅
期末考试之考试传纸条
Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 32 MB
Description
平时不努力,考试得着急呐。传说中的BT监考老师竟然搬来了信号屏蔽工具,手机不管用啦有木有。不过这难不到大家,cxlove见证了同学们使用传统的作弊方式----传纸条,纸条得从A同学传到B同学处,在一个N*M的教室里,零散着坐着一些同学,监考老师游荡在教室某些位置,能否成功将纸条传到B同学处,且不被老师发现。每一次传纸条不能斜传,只能传给前后左右四个同学,监考老师的监视范围为相邻的八个位置,当纸条传到老师监视范围内就会被逮住了,纸条传到空位置处时传送失败。 帮cxlove计算下最少需要多少时间才能完成传纸条。

Input
多组测试数据
第一行两个整数,N,M(1<=N,M<=100),分别表示教室有N*M个位置接下来N行,每行M个字符,表示教室的情况
'A'表示纸条的初始位置,'B'表示纸条的目标位置,'.'表示一般同学的位置,'#'表示当前位置没有人坐,'T'表示监考老师。(可能有多个监考老师)

Output
输出仅一个整数,表示需要的最少时间传到B同学处
如果不能传达,输出-1

Sample Input
OriginalTransformed
5 5
A.T..
.#..#
.....
####.
....B
1 5
A.T.B

Sample Output
OriginalTransformed
8
-1

Source
cxlove
——————————————————————帅气分割线——————————————————————
思路:这道题跟Hero in Maze那道题基本是一样的,都是最裸的bfs,只是多了一点东西。监考老师。话说想起来高考,监考老师什么的,监考就监考吧,咱没有怨言,问题是还要交监考费!这就说不通了,我不想让你监考了,不交钱了,行不?你监考,还问我要钱,又不是我请你来的。这种费用应当是完善自己教育体制的成本,不应当是考生的投资吧!咳咳,跑偏了……首先考虑监考老师周围这个问题。一旦我在输入的时候,输入了一个监考老师,那就意味着它和它周围的八个结点不能访问。但是问题来了,不能访问并不意味着不能设置另一个监考老师。有点像红色警戒里的光棱塔,当下一个光棱塔处于这个光棱塔攻击范围内,防御范围虽然牺牲了一小部分但是就没有盲点了。我们利用vis[ ][ ]数组解决。因为我们在输入地图的时候,是不会判断该结点是否有访问标记的。输入的时候就在监考老师范围的结点上设置访问标记即可。
代码如下:
#include <stdio.h>
#include <memory.h>
#define LIM nx>0&&nx<=n&&ny>0&&ny<=m
int q[10010];//建立队列
int mat[110][110], dis[110][110];
bool vis[110][110];
int dx[8] = {-1, 0, 1, 0, -1, -1, 1, 1}, dy[8] = {0, 1, 0, -1, -1, 1, 1, -1};
int n, m, sx, sy, ox, oy;
char s[110];
int bfs(int x, int y){
    int fron = 0, rear = 0;
    int u = x * 1000 + y;
    vis[x][y] = 1;
    dis[x][y] = 0;
    q[rear++] = u;//起点进队
    while(fron < rear){
        u = q[fron++];//结点更新为当前队首
        x = u / 1000; y = u % 1000;
        for(int d = 0; d < 4; d++){//注意此处是d<4,表示上右下左四个方向,这是传纸条的方向
            int nx = x + dx[d], ny = y + dy[d];
            if(LIM && mat[nx][ny] && !vis[nx][ny]){
                int v = nx * 1000 + ny;
                q[rear++] = v;//偏移处结点进队
                vis[nx][ny] = 1;
                dis[nx][ny] = dis[x][y] + 1;//距离多1
                if(nx == ox&&ny == oy)
                  return dis[nx][ny];//完成任务
            }
        }
    }
    return -1;
}
int main(){
    int i, j, t;
    while(scanf("%d%d", &n, &m) != EOF){
        memset(mat, 0, sizeof(mat));
        memset(vis, 0, sizeof(vis));
        for(i = 1; i <= n; i++){//这次的地图下标是从1开始的
            scanf("%s", s);
            for(j = 1; j <= m; j++){
                switch(s[j-1]){
                    case 'A':mat[i][j] = 1;sx = i; sy = j; break;
                    case 'B':if(!vis[i][j]) {mat[i][j] = 1;ox = i; oy = j;} break;
                    case '.':if(!vis[i][j]) {mat[i][j] = 1;} break;
                    case '#':if(!vis[i][j]) {mat[i][j] = 0;} break;
                    case 'T':vis[i][j] = 1; for(int d = 0; d < 8; d++)  vis[i+dx[d]][j+dy[d]] = 1; break;
                }
            }
        }
        t = bfs(sx, sy);
        printf("%d\n", t);
    }
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值