NYOJ ~ 999 ~ 师傅又被妖怪抓走了(BFS+状压)

思路:BFS。多加一个状态就可以了,状态的变化不是很好写。看代码理解吧。

#include<bits/stdc++.h>  
using namespace std;  
const int MAXN = 105;  
struct node  
{  
    int x,y,state,step;  
}NOW,NEXT;  
int n, m, t, sx, sy, ex1, ey1, ex2, ey2, dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};  
char MAP[MAXN][MAXN];  
bool vis[MAXN][MAXN][4];  
int update(int x,int y,int state)//状态更新   
{  
    bool flag1 = false, flag2 = false;//flag1表示是否找到了D, flag表示是否找到了E   
    if(state == 1) flag1 = true;   
    else if(state == 2) flag2 = true;
    else if(state == 3) { flag1 = true; flag2 = true; }
    for(int i = x; i < n; i++)  
    {  
        if(MAP[i][y] == 'D') flag1 = true;  
        if(MAP[i][y] == 'E') flag2 = true;  
        if(MAP[i][y] != '.') break;  
    }  
    for(int i = x; i >= 0; i--)  
    {  
        if(MAP[i][y] == 'D') flag1 = true;  
        if(MAP[i][y] == 'E') flag2 = true;  
        if(MAP[i][y] != '.') break;  
    }  
    for(int i = y; i < m; i++)  
    {  
        if(MAP[x][i] == 'D') flag1 = true;  
        if(MAP[x][i] == 'E') flag2 = true;  
        if(MAP[x][i] != '.') break;  
    }  
    for(int i = y; i >= 0; i--)  
    {  
        if(MAP[x][i] == 'D') flag1 = true;  
        if(MAP[x][i] == 'E') flag2 = true;  
        if(MAP[x][i] != '.') break;  
    }  
    if(flag1 == false && flag2 == false) return 0;  
    if(flag1 == true  && flag2 == false) return 1;  
    if(flag1 == false && flag2 == true)  return 2;  
    if(flag1 == true  && flag2 == true)  return 3;  
}  
int bfs()  
{  
    memset(vis,0,sizeof(vis));  
    NOW.x = sx; NOW.y = sy; NOW.step = 0; NOW.state = update(sx,sy,0); vis[sx][sy][NOW.state] = true;  
    queue<node> q;  
    q.push(NOW);  
    while(!q.empty())  
    {  
        NOW = q.front();  
        if(NOW.state == 3) return NOW.step;  
        q.pop();  
        for(int i = 0; i < 4; i++)  
        {  
            int X = NOW.x + dir[i][0], Y = NOW.y + dir[i][1], state = update(X,Y,NOW.state);  
            if(X >= 0 && Y >= 0 && X < n && Y < m && vis[X][Y][state] == false && MAP[X][Y] == '.')  
            {  
                vis[X][Y][state] = true;  
                NEXT.x = X; NEXT.y = Y; NEXT.state = state; NEXT.step = NOW.step + 1;   
                q.push(NEXT);  
            }  
        }  
    }  
    return -1;//找不到   
}  
int main()  
{  
    int CASE = 1;  
    while(~scanf("%d%d%d",&n,&m,&t))  
    {  
        for(int i = 0; i < n; i++)  
        {  
            for(int j = 0; j < m; j++)  
            {  
                cin>>MAP[i][j];  
                if(MAP[i][j] == 'S'){ MAP[i][j] = '.'; sx = i; sy = j; }  
            }  
        }  
        printf("Case %d:\n",CASE++);  
        int ans = bfs();  
        if(ans > t) ans = -1;//时间不够用   
        printf("%d\n",ans);  
    }  
    return 0;  
}  




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值