• 洛谷 题解 P2802 【回家】


    思路:DFS+剪枝

    本题可以用一个字符二维数组来存整个地图,然后在往四个方向进行搜索。注意:当走到家门前要先判断血量!(本人就被坑了)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=110;
    int n,m;
    int Begin_x,Begin_y,End_x,End_y;
    int ans=0x7ffffff;
    char Map[N][N];
    bool t[N][N];
    int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};
    int sm=6;
    inline void dfs(int x,int y,int tot)
    {
        bool four=false;
        if(x==End_x&&y==End_y&&sm>0)
        {
            ans=min(ans,tot);
            return;
        }
        for(int i=1;i<=4;i++)
        {
            int a=x+dx[i],b=y+dy[i];
            if(a>0&&b>0&&a<=n&&b<=m&&(sm-1>0||Map[a][b]=='4')&&Map[a][b]!='0'&&!t[a][b])
            {
                sm--;
                t[x][y]=true;
                if(Map[x][y]=='4')sm=6,four=true,Map[x][y]='1';
                dfs(a,b,tot+1);
                sm++;
                t[x][y]=false;
                if(four)Map[x][y]='4';
            }
        }
    }
    inline int read()
    {
        int tot=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9')
        {
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9')
        {
            tot=tot*10+c-'0';
            c=getchar();
        }
        return tot*f;
    }
    int main()
    {
        n=read();
        m=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>Map[i][j];
                if(Map[i][j]=='2')Begin_x=i,Begin_y=j;
                else if(Map[i][j]=='3')End_x=i,End_y=j;
            }
        }
        //cout<<Begin_x<<" "<<Begin_y<<endl<<End_x<<" "<<End_y<<endl;
        dfs(Begin_x,Begin_y,0);
        if(ans==0x7ffffff)cout<<-1<<endl;
        else cout<<ans<<endl;
        return 0;
    }
    

    信心满满地提交,什么?90分??!

    下了第九个测试点,发现小H栽死在家门口了。

    修改了半天,改成了这样:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=110;
    int n,m;
    int Begin_x,Begin_y,End_x,End_y;
    int ans=0x7ffffff;
    char Map[N][N];
    bool t[N][N];
    int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};
    int sm=6;
    inline void dfs(int x,int y,int tot)
    {
        bool four=false;
        if(sm<=0||tot>=ans)return;
        if(x==End_x&&y==End_y)
        {
        	//cout<<sm<<" "<<tot<<endl;
            ans=min(ans,tot);
            return;
        }
        for(int i=1;i<=4;i++)
        {
            int a=x+dx[i],b=y+dy[i];
            if(a>0&&b>0&&a<=n&&b<=m&&Map[a][b]!='0'&&!t[a][b])
            {
                sm--;
                t[x][y]=true;
                if(Map[x][y]=='4')sm=6,four=true,Map[x][y]='1';
                dfs(a,b,tot+1);
                sm++;
                t[x][y]=false;
                if(four)Map[x][y]='4',sm-=6;
            }
        }
    }
    inline int read()
    {
        int tot=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9')
        {
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9')
        {
            tot=tot*10+c-'0';
            c=getchar();
        }
        return tot*f;
    }
    int main()
    {
        n=read();
        m=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>Map[i][j];
                if(Map[i][j]=='2')Begin_x=i,Begin_y=j;
                else if(Map[i][j]=='3')End_x=i,End_y=j;
            }
        }
        //cout<<Begin_x<<" "<<Begin_y<<endl<<End_x<<" "<<End_y<<endl;
        dfs(Begin_x,Begin_y,0);
        if(ans==0x7ffffff)cout<<-1<<endl;
        else cout<<ans<<endl;
        return 0;
    }
    

    这回没问题了吧......

    然而只有80分

    没有处理好特殊的‘4’

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=110;
    int n,m;
    int Begin_x,Begin_y,End_x,End_y;//存起始坐标与终止坐标
    int ans=0x7ffffff;//答案
    char Map[N][N];//存地图
    bool t[N][N];//判断有没有走过
    int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};//四个方向
    int sm=6;//存生命
    inline void dfs(int x,int y,int tot)
    {
        bool four=false;//判断这格是不是4
        if(sm<=0||tot>=ans)return;//剪枝
        if(x==End_x&&y==End_y)//更新答案
        {
            ans=min(ans,tot);
            return;
        }
        for(int i=1;i<=4;i++)//四个方向搜索
        {
            int a=x+dx[i],b=y+dy[i];
            if(a>0&&b>0&&a<=n&&b<=m&&Map[a][b]!='0'&&!t[a][b])
            {
                sm--;
                t[x][y]=true;//设置为已走
                int lssm=sm+1;//存一下当前生命+1(以便在回溯时候用)
                if(Map[x][y]=='4')sm=6,four=true,Map[x][y]='1';//判断4的情况
                dfs(a,b,tot+1);//搜索
                sm++;
                t[x][y]=false;
                if(four)Map[x][y]='4',sm=lssm;
            }
        }
    }
    inline int read()//然而加不加都一样
    {
        int tot=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9')
        {
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9')
        {
            tot=tot*10+c-'0';
            c=getchar();
        }
        return tot*f;
    }
    int main()
    {
        n=read();
        m=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>Map[i][j];
                if(Map[i][j]=='2')Begin_x=i,Begin_y=j;
                else if(Map[i][j]=='3')End_x=i,End_y=j;
            }
        }
        dfs(Begin_x,Begin_y,0);//DFS
        if(ans==0x7ffffff)cout<<-1<<endl;//特判
        else cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    小心!你被“大数据”锁定了
    深入浅出安卓,怎样从零学好移动开发
    Cocos2d-x3.0触摸
    将Spring源代码导入eclipse步骤
    vertica时间计算SQL语句实例:统计一天内登录的用户
    cocos2d-x 2.2 创建项目
    Codeforces-475B Strongly Connected City
    java socket通信-传输文件图片--传输图片
    listView解决滑动时黑色背景问题
    UVa 10450
  • 原文地址:https://www.cnblogs.com/hulean/p/10799259.html
Copyright © 2020-2023  润新知