hdu 5024 Wang Xifeng's Little Plot | bfs

题意:

在所给的图中(每个点有8个方向可以走)找出一条路径,并且这条路径最多只有一个90度的角。使得这条路径的长度最长。

思路:

*当时看到这题好开心,之前在刘汝佳那本书上做过类似的,WA了三次到最后都没调出来哪里错了= =。进爷看我如此乏力,遂上去直接搞了一发,直接A了。Orz

进爷做法是每次都枚举一个点的八个方向,直走一段距离,然后转一个弯,看看所能获得的最大距离,两个距离加起来即可。

bfs:

dis[x][y][d],表示走到(x,y)点朝向为d的最远距离;

cot[x][y][d],表示走到(x,y)点朝向为d时是否有转过弯;(0:无;1:有)

AC代码:

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 105;
const int INF = 0x3f3f3f3f;
int dir[8][2] = {{0,1}, {-1,1}, {-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
int dis[MAXN][MAXN][10];
int cot[MAXN][MAXN][10];
char ch[MAXN][MAXN];
int n;
struct pp
{
        int x, y, z;
};
void bfs(int h1, int h2, int h3)
{
        dis[h1][h2][h3] = 1;
        queue <pp> q;
        q.push((pp){h1, h2, h3});
        while(!q.empty())
        {
                pp e = q.front();
                q.pop();
                int x, y, z;
                for(int i = 0;i < 8; i++)
                {
                        x = e.x+dir[i][0], y = e.y+dir[i][1], z = i;
                        int tmp =( e.z+6 )% 8, tmp2 = (e.z+2)%8;
                        if(i != tmp2 && i != tmp && i != e.z)  continue;    //fangxiangbudui
                        if(e.z != z && cot[e.x][e.y][e.z] == 1) continue;   //ever turn;
                        if(x >= 0 && y >= 0 && x < n && y < n && (dis[e.x][e.y][e.z] + 1 > dis[x][y][z]||(dis[e.x][e.y][e.z]+1 == dis[x][y][z] && cot[e.x][e.y][e.z] == 0)) && ch[x][y] != '#')// ||后面的那个条件调死我了!!后来才醒悟,如果距离相等,肯定要没转过弯的。
                        {
                                dis[x][y][z] = dis[e.x][e.y][e.z]+1;
                                cot[x][y][z] = cot[e.x][e.y][e.z];
                                if(e.z != z)    cot[x][y][z] = 1;
                                q.push((pp){x, y, z});
                        }
                }
        }
}

int main()
{
        while(scanf("%d", &n), n)
        {
                memset(dis, 0, sizeof(dis));
                memset(cot, 0, sizeof(cot));
                getchar();
                for(int i = 0;i < n; i++)
                        scanf("%s", ch[i]);
                //
                for(int i = 0;i < n; i++)
                {
                        for(int j = 0;j < n; j++)
                        {
                                if(ch[i][j] == '#') continue;
                                for(int z = 0;z < 8; z++)
                                {
                                        if(dis[i][j][z] != 0) continue;
                                        bfs(i, j, z);
                                }
                        }
                }
                //
                int res = 2;
                for(int i = 0;i < n; i++)
                {
                        for(int j = 0;j < n; j++)
                        {
                                if(ch[i][j] == '#') continue;
                                for(int z = 0;z < 8; z++)
                                        res = max(res, dis[i][j][z]);
                        }
                }
                printf("%d\n", res);
        }
        return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值