NOIP2017 棋盘

题目传送门(洛咕)

题目描述

有一个m×m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上、 下、左、 右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费1个金币。

另外, 你可以花费2个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法; 只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?

输入格式

第一行包含两个正整数m, n以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。

接下来的nn行,每行三个正整数x, y, c,分别表示坐标为(x,y)的格子有颜色c。

其中c=1代表黄色,c=0代表红色。 相邻两个数之间用一个空格隔开。 棋盘左上角的坐标为(1,1),右下角的坐标为(m,m)。

棋盘上其余的格子都是无色。保证棋盘的左上角,也就是(1,1) 一定是有颜色的。

输出格式

一个整数,表示花费的金币的最小值,如果无法到达,输出-1

输入输出样例

输入 #1
5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0
输出 #1
8
输入 #2
5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0
输出 #2
-1
 这道题算是进年来PJT3较为简单的一道,但也有很多需要注意的地方:
1.魔法只会用在空地上(显然用不着改变非同色地形)
2.用book记录会T
3.并不是只可以向右下走
这道题一上来我选的深搜(不知道为什么。。。
没有记忆,用了book,爆T55分
#include
typedef long long ll;
using namespace std;
int a[105][105];
int ans=999999999;
int n,m;
int xb=0;
int book[105][105];
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=0; c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    return f?x:-x;
}
void dfs(int x,int y,int flag,int cnt,int col)
{
    if(x==n&&y==n)
    {
        xb=1;
        ans=min(ans,cnt);
        return;
    }
    if(book[x][y+1]==0)
    {
        book[x][y+1]=1;
        if(col==a[x][y+1]) dfs(x,y+1,0,cnt,a[x][y+1]);
        else if(col!=a[x][y+1]&&a[x][y+1]!=0) dfs(x,y+1,0,cnt+1,a[x][y+1]);
        else if(a[x][y+1]==0&&flag==0) dfs(x,y+1,1,cnt+2,a[x][y]);
        book[x][y+1]=0;
    }
    if(book[x+1][y]==0)
    {
        book[x+1][y]=1;
        if(col==a[x+1][y]) dfs(x+1,y,0,cnt,a[x+1][y]);
        else if(col!=a[x+1][y]&&a[x+1][y]!=0) dfs(x+1,y,0,cnt+1,a[x+1][y]);
        else if(a[x+1][y]==0&&flag==0) dfs(x+1,y,1,cnt+2,a[x][y]);
        book[x+1][y]=0;
    }
    if(book[x][y-1]==0)
    {
        book[x][y-1]=1;
        if(col==a[x][y-1]) dfs(x,y-1,0,cnt,a[x][y-1]);
        else if(col!=a[x][y-1]&&a[x][y-1]!=0) dfs(x,y-1,0,cnt+1,a[x][y-1]);
        else if(a[x][y-1]==0&&flag==0) dfs(x,y-1,1,cnt+2,a[x][y]);
        book[x][y-1]=0;
    }
    if(book[x-1][y]==0)
    {
        book[x-1][y]=1;
        if(col==a[x-1][y]) dfs(x-1,y,0,cnt,a[x-1][y]);
        else if(col!=a[x-1][y]&&a[x-1][y]!=0) dfs(x-1,y,0,cnt+1,a[x-1][y]);
        else if(a[x-1][y]==0&&flag==0) dfs(x-1,y,1,cnt+2,a[x][y]);
        book[x-1][y]=0;
    }
}
int main()
{
    memset(book,-1,sizeof(book));
    int x,y,z;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            book[i][j]=0;
    for(int i=1;i<=m;i++)
    {
        x=read(); y=read(); z=read();
        a[x][y]=z+1;
    }
    dfs(1,1,0,0,a[1][1]);
    if(xb==1) cout<<ans;
    else cout<<-1;
    return 0;
}

后来加了记录最优情况的剪枝,A了

#include
typedef long long ll;
using namespace std;
int a[105][105];
int ans=999999999;
int n,m;
int xb=0;
int js[105][105];
int book[105][105];
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=0; c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    return f?x:-x;
}
void dfs(int x,int y,int flag,int cnt,int col)
{
    if(js[x][y]<=cnt) return;
    js[x][y]=min(js[x][y],cnt);
    if(x==n&&y==n)
    {
        xb=1;
        ans=min(ans,cnt);
        return;
    }
    if(book[x][y+1]==0)
    {
        if(col==a[x][y+1]) dfs(x,y+1,0,cnt,a[x][y+1]);
        else if(col!=a[x][y+1]&&a[x][y+1]!=0) dfs(x,y+1,0,cnt+1,a[x][y+1]);
        else if(a[x][y+1]==0&&flag==0) dfs(x,y+1,1,cnt+2,a[x][y]);
    }
    if(book[x+1][y]==0)
    {
        if(col==a[x+1][y]) dfs(x+1,y,0,cnt,a[x+1][y]);
        else if(col!=a[x+1][y]&&a[x+1][y]!=0) dfs(x+1,y,0,cnt+1,a[x+1][y]);
        else if(a[x+1][y]==0&&flag==0) dfs(x+1,y,1,cnt+2,a[x][y]);
    }
    if(book[x][y-1]==0)
    {
        if(col==a[x][y-1]) dfs(x,y-1,0,cnt,a[x][y-1]);
        else if(col!=a[x][y-1]&&a[x][y-1]!=0) dfs(x,y-1,0,cnt+1,a[x][y-1]);
        else if(a[x][y-1]==0&&flag==0) dfs(x,y-1,1,cnt+2,a[x][y]);
    }
    if(book[x-1][y]==0)
    {
        if(col==a[x-1][y]) dfs(x-1,y,0,cnt,a[x-1][y]);
        else if(col!=a[x-1][y]&&a[x-1][y]!=0) dfs(x-1,y,0,cnt+1,a[x-1][y]);
        else if(a[x-1][y]==0&&flag==0) dfs(x-1,y,1,cnt+2,a[x][y]);
    }
}
int main()
{
    memset(book,-1,sizeof(book));
    memset(js,127,sizeof(js));
    int x,y,z;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            book[i][j]=0;
    for(int i=1;i<=m;i++)
    {
        x=read(); y=read(); z=read();
        a[x][y]=z+1;
    }
    dfs(1,1,0,0,a[1][1]);
    if(xb==1) cout<<ans;
    else cout<<-1;
    return 0;
}

 


你可能感兴趣的:(NOIP2017 棋盘)