[USACA] Bronze Lotus Pool [2]

Keywords: REST

Preface

Searching for friends in this article, it is so coincident that we are mostly a school. Why?Because the title is Anemone Pool.

subject

[Problem Description]

FJ built a beautiful pond for the cows to exercise.The rectangular pool is divided into M rows and N columns (square grid).Some lattices have lotus flowers, some rocks, and the rest are just beautiful, pure, blue water.
Bessie is practicing ballet. She jumps from one lotus flower to another, currently in a lotus flower.She wants to jump on the lotus one by one, with the goal being another given lotus.She can't jump into the water or onto a rock.Bessie's jumps are like a knight in chess: move 1 horizontally, move 2 vertically, or move 1 vertically, move 2 horizontally.So Bessie may sometimes have up to eight chosen jumps.
FJ watches Bessie's ballet and realizes that sometimes Bessie may not be able to reach her destination because there are no lotuses on the way.So he wanted to add a few lotus flowers so Bessie could finish the task.The consistently frugal FJ wants to add the least amount of lotus flowers.Of course, lotus flowers cannot be placed on stones.
Help FJ determine the minimum number of lotuses that must be added.Based on the minimum number of lotus flowers added, the minimum number of steps required for Bessie to jump from the starting point to the target point was calculated.Finally, the number of leap paths that skip the minimum number of steps when the minimum number of lotus flowers added is calculated.

[Input Format]

Line 1: Two integers M,N.
Line 2..M+1: Line i+1, Line i+1 has N integers indicating the status of the location: 0 is water, 1 is lotus, 2 is rock, 3 is where Bessie begins, and 4 is where Bessie is going.

[Output Format]

Line 1: An integer: the minimum number of lotuses to add. If Bessie can't jump to it anyway, output-1.
Line 2: An integer: The minimum number of steps required for Bessie to jump from the starting point to the target point, based on the minimum number of lotus flowers added.If the first line outputs -1, this line does not output.
Line 3: An integer: Number of skip paths where the minimum number of lotus flowers added is the value output in line 2. If line 1 outputs -1, this line does not output.

[Input Sample]

4 8
0 0 0 1 0 0 0 0
0 0 0 0 0 2 0 1
0 0 0 0 0 4 0 0
3 0 0 0 0 0 1 0

[Output Sample]

2
6
2

[Sample explanation]

Add at least two lotus flowers and place them at'x'.
0 0 0 1 0 0 0 0    0 0 0 1 0 0 0 0
0 x 0 0 0 2 0 1    0 0 0 0 0 2 0 1
0 0 0 0 x 4 0 0    0 0 x 0 x 4 0 0
3 0 0 0 0 0 1 0    3 0 0 0 0 0 1 0
Bessie has at least six steps to jump. There are two options
0 0 0 C 0 0 0 0    0 0 0 C 0 0 0 0
0 B 0 0 0 2 0 F    0 0 0 0 0 2 0 F
0 0 0 0 D G 0 0    0 0 B 0 D G 0 0
A 0 0 0 0 0 E 0    A 0 0 0 0 0 E 0

[Data Range]

1 ≤ M ≤ 30
1 ≤ N ≤ 30

Analysis

This topic analysis is the most important. To be honest, I have looked for a lot of solutions, but I just looked at the code that I don't understand and I thought it through.
The first question is clever. The first reaction is a furious search, which should not be possible. So the algorithm to find a comprehensive point, as a minimum value, is still on the chessboard, combined with the bronze lotus pool [1]. It should be thought that this is an implicit map search, but because only to increase the number of lotus flowers, this is the shortest path with power, which can be made with SPFA or DIJ.Code implementation is not difficult

Then let's look at Subject 2, I output a path for debugging with fa mapping, change it to get the answer to Subject 3, and then let's look at Subject 3

The number of scenarios should be a dp, but here there are two constraints, one is the lotus increase number and the other is the shortest path.
Actually, I have been entangled for a long time, but I didn't think of any other way, so I wrote this hard-won idea directly: In order to get the correct father node, we make two marks, one is the number of lotus flowers, the other is the shortest path in the minimum number of lotus flowers, open with two two two two two two two-dimensional arrays to see the code.
With these two arrays, because this is a DAG graph, you can memorize dp from the back to the front, and the second array also makes the second sub-topic directly.

Code

#include<map>
#include<cmath>
#include<queue> 
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm> 
using namespace std;
const int maxn=35,inf=maxn*maxn*10;
typedef long long LL;
int a[maxn][maxn],dist[maxn][maxn],mind[maxn][maxn];
LL dp[maxn][maxn];
int ans1,ans2,ans3;
int n,m;
int dx[]={1,1,-1,-1,2,2,-2,-2};
int dy[]={2,-2,2,-2,1,-1,1,-1};
struct data
{
    int x,y;
    friend bool operator<(data a,data b)
    {
        return a.x!=b.x?a.x<b.x:a.y<b.y;//Before!= Written==..A little unhappy
    }
}u,v;
map<data,data>fa;
void Init()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            if(a[i][j]==3)
                u=(data){i,j};
            if(a[i][j]==4)
                v=(data){i,j};
        }
    }
}
bool inq[maxn][maxn];
void outpath(data x)
{

    if(fa[x].x!=x.x||fa[x].y!=x.y)
        outpath(fa[x]);
    cout<<x.x<<" "<<x.y<<endl;
}
int get_step(data x)
{
    if(fa[x].x!=x.x||fa[x].y!=x.y)
    {
        return get_step(fa[x])+1;
    }
    return 0;
}
void solve1and2()
{
    queue<data>q;
    q.push(u);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            dist[i][j]=inf;
            mind[i][j]=inf;
        }
    }
    dist[u.x][u.y]=0;
    mind[u.x][u.y]=0;
    fa[u]=u;
    while(!q.empty())
    {
        data i=q.front();q.pop();
        inq[i.x][i.y]=0;
        for(int k=0;k<8;k++)
        {
            int nx=i.x+dx[k],ny=i.y+dy[k];
            if(nx<1||ny<1||nx>n||ny>m)continue;
            if(a[nx][ny]==2)continue;
            if(a[nx][ny]==0)
            {
                if(dist[i.x][i.y]+1==dist[nx][ny])
                    mind[nx][ny]=min(mind[i.x][i.y]+1,mind[nx][ny]);
                if(dist[i.x][i.y]+1<dist[nx][ny])
                {
                    dist[nx][ny]=dist[i.x][i.y]+1;
                    fa[(data){nx,ny}]=(data){i.x,i.y};
                    mind[nx][ny]=mind[i.x][i.y]+1;
                    if(inq[nx][ny])continue;
                    inq[nx][ny]=1;
                    q.push((data){nx,ny});
                }
            }
            else
            {
                if(dist[i.x][i.y]==dist[nx][ny])
                    mind[nx][ny]=min(mind[i.x][i.y]+1,mind[nx][ny]);
                if(dist[i.x][i.y]<dist[nx][ny])
                {
                    fa[(data){nx,ny}]=(data){i.x,i.y};
                    dist[nx][ny]=dist[i.x][i.y];
                    mind[nx][ny]=mind[i.x][i.y]+1;
                    if(inq[nx][ny])continue;
                    inq[nx][ny]=1;
                    q.push((data){nx,ny});
                }
            }
        }
    }
    ans1=dist[v.x][v.y];
    ans2=mind[v.x][v.y];
    if(ans1>=inf)
        ans1=-1;
    cout<<ans1<<endl;
    if(ans1!=-1)
        cout<<ans2<<endl;
}
LL f(int x,int y)
{
    if(dp[x][y]!=-1)
        return dp[x][y];
    if(x==u.x&&y==u.y)
        return 1;
    LL ret=0;
    for(int k=0;k<8;k++)
    {
        int nx=x+dx[k],ny=y+dy[k];
        if(nx<1||ny<1||nx>n||ny>m)continue;
        if(a[nx][ny]==2)continue;
        if(a[x][y]==0)
        {
            if(mind[nx][ny]+1==mind[x][y]&&dist[nx][ny]+1==dist[x][y])
                ret+=f(nx,ny);
        }
        else
        {
            if(mind[nx][ny]+1==mind[x][y]&&dist[nx][ny]==dist[x][y])
                ret+=f(nx,ny);
        }
    }
    return dp[x][y]=ret;
}
void Debug()
{
    for(int i=1;i<=4;i++)
    {
        for(int j=1;j<=4;j++)
        {
            cout<<dist[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
    for(int i=1;i<=4;i++)
    {
        for(int j=1;j<=4;j++)
        {
            cout<<mind[i][j]<<" ";
        }
        cout<<endl;
    }
}
void solve3()
{
    memset(dp,-1,sizeof(dp));
    cout<<f(v.x,v.y);
}
int main()
{
    //freopen("in.txt","r",stdin);
    Init();
    solve1and2();
    //Debug();
    if(ans1!=-1)
        solve3();
    return 0;
}

Attention issues
1. About mapping, we must overload the <operator. Sometimes there is a miserable problem. I debugged the first solution of the second question for 20 minutes before I discovered it. In the future, the structure custom symbol operation will be verified.
2. Note this dp's judgment condition, can walk over is to determine the new node, whether use or not new lotus is to see its own node
3. Program Number Open LL

Note: For fa implementation, this useless code was deliberately left behind

About BFS

BFS output paths are fa arrays, FA arrays are generally arrays, structs or numbers are too large use map, remember the overloaded operator'<'

About the Number of Paths

Generally for DAG diagrams, it is a memory dp that can be made. Each step of the selection can see whether it just came from the step you are ready to select?

Posted by B-truE on Sun, 09 Jun 2019 09:27:31 -0700