【HDOJ 5335】Walk Out

【HDOJ 5335】Walk Out

DFS或者BFS 需要极大的剪枝叶否则必超

BFS做的 起点1的话正常搜 0的话从起点找离终点距离最近(x+y最大)的几个点放在队列中然后再搜

搜的时候也要剪枝 用一个变量存放当前搜到的点在最终结果中处在的位置 然后再比较与最近距离还有该点已匹配的字符(‘1’/’0’) 任何一项不优 continue 在注意些特判之类的 A的也挺累。。。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f

using namespace std;

typedef struct Point
{
    int x,y,step;
}Point;

bool vis[1111][1111];
char str[1111111];
char mp[1111][1111];
int m,n;
int dirx[] = {-1, 0, 0, 1};
int diry[] = { 0,-1, 1, 0};
int dd[1111111];

bool in(int x,int y) { return (x > 0 && x <= m && y > 0 && y <= n);}

bool bfs()
{
    int d = 0,i,x,y,st,s;
    Point p;
    memset(vis,0,sizeof(vis));
    queue <Point> ls;
    queue <Point> q;
    if(mp[1][1] == ‘1‘) q.push(Point{1,1,0});
    else ls.push(Point{1,1,0});
    vis[1][1] = 1;
    while(!ls.empty())
    {
        p = ls.front();
        ls.pop();

        if(p.x == m && p.y == n) return true;
        for(i = 0; i < 4; ++i)
        {
            x = p.x + dirx[i];
            y = p.y + diry[i];
            if(!in(x,y) || vis[x][y]) continue;
            if(mp[x][y] == ‘1‘)
            {
                if(x+y > d)
                {
                    d = x+y;
                    while(!q.empty()) q.pop();
                }
                q.push(Point{x,y,0});
        //printf("%d %d\n",x,y);
            }
            else ls.push(Point{x,y,0});
            vis[x][y] = 1;
        }
    }
    memset(str,0,sizeof(str));
    str[0] = ‘1‘;
    memset(dd,0,sizeof(dd));
    s = 0;
    while(!q.empty())
    {
        p = q.front();
        q.pop();
        x = p.x;
        y = p.y;
        st = p.step;
        if(x == m && y == n && st == 0) return false;
        if(st != 0 && (mp[x][y] > str[st] || x+y < dd[st]) )continue;

        for(i = 0; i < 4; ++i)
        {
            x = p.x + dirx[i];
            y = p.y + diry[i];
            if(!in(x,y) || vis[x][y]) continue;

            if(!str[st+1] )
            {
                dd[st+1] = x+y;
                str[st+1] = mp[x][y];
            }
            else if(dd[st+1] < x+y)
            {
                dd[st+1] = x+y;
                str[st+1] = mp[x][y];
            }
            else if(x + y == dd[st+1]) str[st+1] = min(str[st+1],mp[x][y]);
            else continue;

            if(x == m && y == n) return false;

            q.push(Point{x,y,st+1});
            vis[x][y] = 1;
        }
    }
    return false;
}

int main()
{
    //freopen("in.in","r",stdin);
    //freopen("out.out","w",stdout);
    int t,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&m,&n);
        for(i = 1; i <= m; ++i)
            scanf("%s",mp[i]+1);
        if(bfs()) printf("0\n");
        else printf("%s\n",str);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 03:12:22

【HDOJ 5335】Walk Out的相关文章

【HDU 5335】Walk Out(BFS)

这道题卡时间卡的比较紧. 一开始直接BFS 毫无疑问的超时,之后想到根据BFS的常规优化思想,去选择起始点进行遍历. 这样我们一开始先BFS一次,这次的BFS是选择出这一点为1并且从起点到这一个点,中间路径的点全为0的点. 这样选择出这个点之后,这个点到终点的路径长度就可以断定了. 之后我们把所有到终点距离最小的点放在一个容器里进行BFS. 这道题没有做出来的原因很大一部分就是对BFS的理解不够深以及该有的贪心思路没有,导致了这道题没有AC. 嗯,有句话说的对:综合是第一生产力. #includ

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

【HDOJ 4768】 Flyer (等差数列+二分)

[HDOJ 4768] Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2022    Accepted Submission(s): 743 Problem Description The new semester begins! Different kinds of student soc

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【HDOJ 5384】Danganronpa

[HDOJ 5384]Danganronpa AC自动机...当时感觉用字典树 标神也往自动机想来着..手太生加上时间紧迫也没敲--回来一看题解什么AB同时建自动机...顿时愣了 什么叫同时建= =问了问财神说普通自动机...B串单建 立马疯了--这不就是模板题么... B串建自动机 A串枚举查询 写完兴冲冲1T--立马想法优化 建fail时压缩一下 查询时直接累计 不再循环找fail 171ms...第二个自动机的题..距上次蛮久了 这次一复习 感觉印象差不多有了 代码(模板)如下: #inc

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

【HDOJ 4686】 Arc of Dream (矩阵快速幂)

[HDOJ 4686] Arc of Dream (矩阵快速幂) 两个公式 a(i) = a(i-1)*Ax+Ay b(i) = b(i-1)*Bx+By 求 0~(n-1) 的a(i)*b(i) 初始矩阵为                                       求幂矩阵为 a0                                                      Ax          0           0          0        

【HDOJ 1005】 CRB and His Birthday

[HDOJ 1005] CRB and His Birthday 背包 商场卖东西 没件物品有对应的价值 同时由于超市老板跟你是好绩优...每买一件物品给你a个糖果 同时如果购买某物品 会给对应的b种糖果 即买x个i 可以得到ai*x+bi个糖果 问怎么能得到最多糖果 开始是想开个bool标记每个状态某糖果买每买 还有在该状态是否第一次买某种糖果 写着写着写不好了-- 后来突然想到 可以把每件物品拆开 由于每种物品只赠送一次b 可以把赠b的物品作为"特卖品" 其余为正常送a的物品 这样

【HDOJ 4970】 Killing Monsters

[HDOJ 4970] Killing Monsters 数据很大 立马想预处理 每只怪物会从点x出现移动到点n(终点) 问能剩几只怪物 预处理求出每个位置到终点所受伤害 出现一只怪物直接判断死活即可 代码如下: #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <queue>