洛谷 题解 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;
}
posted @ 2019-05-01 10:16  hulean  阅读(539)  评论(0编辑  收藏  举报