EOJ 1162 tom and jerry bfs

说是用到bfs,其实我们注意到每次只有一个状态进队,所以根本不需要队列。

另外注意,这道题转弯也耗时间,一开始我误以为转方向和直行总共耗时1,实际上这是两个过程,所以总耗时是2。

而且有可能tom和jerry根本不可能相遇,所以我们设置如果耗时超过1000000就认为是无法相遇。

代码如下:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <fstream>
#include <istream>
#include <ostream>
#include <complex>
#include <cstring>
#include <utility>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <new>
#include <set>
#include <map>
#define lson l, m, k << 1
#define rson m, r, k << 1| 1
 
using namespace std;
 
char G[15][15];
struct Node{
    int x, y, dir;
    Node(int a, int b, int c){x = a; y = b; dir = c;}
};
 
Node Move(Node a){//直走
    switch(a.dir){
        case 0:{
            a.x -= 1;
            break;
        }
        case 1:{
            a.y -= 1;
            break;
        }
        case 2:{
            a.x += 1;
            break;
        }
        case 3:{
            a.y += 1;
            break;
        }
    }
    return a;
}
 
bool judge(Node a){
    if (a.x>=0&&a.y>=0&&a.x<10&&a.y<10&&G[a.x][a.y]!='*') return true;
    return false;
}
 
void bfs(){
    int x1, y1, x2, y2;
    for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++){
        if (G[i][j] == 'C'){x1 = i; y1 = j;}
        if (G[i][j] == 'M'){x2 = i; y2 = j;}
    }
 
    Node a(x1, y1, 0), b(x2, y2, 0);
    for (int i = 1;; i++){
        Node aa = Move(a), bb = Move(b);
        if (judge(aa)){
            a = Move(a);
        }else a.dir = (a.dir + 3) % 4;
        if (judge(bb)){
            b = Move(b);
        }else b.dir = (b.dir + 3) % 4;//直走不行就转弯
 
        if (a.x == b.x && a.y == b.y){
            printf("%d\n", i);
            break;
        }
        if (i > 1000000){printf("-1\n"); break;}
    }
}
 
int main()
{
    //freopen("1.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--){
        for (int i = 0; i < 10; i++)
            scanf("%s", G[i]);
 
        bfs();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值