2015 Multi-University Training Contest 4 -- Walk Out

本文探讨了一段代码在处理二进制路径问题时出现栈溢出的原因,并提出通过增加栈大小和优化数据结构来解决的方法。文章还介绍了如何使用优先队列和深度优先搜索(DFS)进行预处理和路径查找,最终实现高效且稳定的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码写的搓,结果爆栈了,加个扩栈的就好了,整体思路就是按向下、向右的法则走,因为终点在右下角,这样走能确保二进制长度最短,然后考虑下前导零的情况,我们可以先用dfs预处理下零点的情况,把离终点近的点插到优先队列里,写的比较暴力,还在服务器6,没TLE。

#pragma comment(linker, "/STACK:102400000,102400000")  //C++
int size = 256 << 20; // 256MB  
char *p = (char*)malloc(size) + size;  
__asm__("movl %0, %%esp\n" :: "r"(p));  //G++ 貌似杭电编译不过
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>

using namespace std;

#pragma comment(linker, "/STACK:102400000,102400000")

char mp[1005][1005];

int n, m;

bool vis[1005][1005], v[1005][1005];

struct point
{
    string ans;
    int x, y;
    friend bool operator < (point a,point b)
    {
        return a.ans>b.ans;
    }
};

int dirx[] = {0, 1};

int diry[] = {1, 0};

int dirxx[] = {0, 1, -1, 0};

int diryy[] = {1, 0, 0, -1};

bool judge(int x, int y)
{
    return (x >= 0 && x < n && y >= 0 && y < m && !vis[x][y]);
}

bool Judge(int x, int y)
{
    return (x >= 0 && x < n && y >= 0 && y < m && !v[x][y]);
}

priority_queue <point> q;

point ok;

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

bool flag = false;

vector <point> Q;int minn=5000;

void dfs(int x, int y)
{
    if(x == n - 1 && y == m - 1)flag = true;
    bool f = false;
    for(int i = 0; i < 4; ++i)
    {
        int nx = x + dirxx[i];
        int ny = y + diryy[i];
        if(judge(nx, ny))
        {
            if(mp[nx][ny] == '0')
            {
                f = true;
                vis[nx][ny] = true;
                dfs(nx, ny);
            }
        }
    }
    if(!f)
    {
        for(int i = 0; i < 2; ++i)
        {
            int xx = x + dirx[i], yy = y + diry[i];
            if(isok(xx, yy))
            {
                if(mp[xx][yy]=='0')continue;
                ok.x = xx;
                ok.y = yy;
                if(v[xx][yy])continue;
                ok.ans = "1";
                minn=min(minn,abs(xx-n)+abs(yy-m));
                Q.push_back(ok);
                v[xx][yy] = true;
            }
        }
    }
}

string bfs()
{
    point F, N;
    bool f;
    while(!q.empty())
    {
        F = q.top();
        q.pop();
        f = true;
        if(F.x == n-1 && F.y == m-1)return F.ans;
        for(int i = 0; i < 2; ++i)
        {
            N.x = F.x + dirx[i];
            N.y = F.y + diry[i];
            if(Judge(N.x, N.y))
                if(mp[N.x][N.y] == '0')
                {
                    f = false;
                    N.ans = F.ans + '0';
                    q.push(N);
                    v[N.x][N.y] = true;
                }
        }
        if(f)
        {
            for(int i = 0; i < 2; ++i)
            {
                N.x = F.x + dirx[i];
                N.y = F.y + diry[i];
                if(Judge(N.x, N.y))
                {
                    N.ans = F.ans + '1';
                    q.push(N);
                    v[N.x][N.y] = true;
                }
            }
        }
    }
}



int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);
        getchar();Q.clear();minn=5000;
        for(int i = 0; i < n; ++i)
        {
            scanf("%s", &mp[i]);
        }
        while(!q.empty())q.pop();
        flag = false;
        memset(vis, false, sizeof(vis));
        memset(v, false, sizeof(v));
        if(mp[0][0] == '0')
        {
            dfs(0, 0);
            int len=Q.size();
            for(int i=0;i<len;++i)
            {
                if(abs(Q[i].x-n)+abs(Q[i].y-m)==minn)
                {
                    q.push(Q[i]);
                }
            }
        }
        else
        {
            ok.ans = "1";
            ok.x = 0;
            ok.y = 0;
            q.push(ok);
        }
        memset(v, false, sizeof(v));v[0][0]=true;
        if(flag)
        {
            puts("0");
            continue;
        }
        string x = bfs();
        int i, len = x.length();
        for(i = 0; i < len; ++i)
        {
            if(x[i] != '0')break;
        }
        if(i == len)puts("0");
        else
        {
            for(; i < len; ++i)putchar(x[i]);
            puts("");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值