棋盘 【计蒜客】【dfs】【bfs】

在这里插入图片描述

dfs 记忆化搜索

#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
const int N=110;
int n,m;
int dis[N][N],g[N][N];

int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};

void dfs(int x,int y,int res,int col)
{
    
    if(x<1||y<1||x>m||y>m||dis[x][y]<=res) return;//判断边界
    dis[x][y]=min(dis[x][y],res);//更新d数组的值
    for(int i=0;i<4;i++)
    {
        int _x=x+dx[i];
        int _y=y+dy[i];
        if(!g[_x][_y]&&!g[x][y]) continue;//两个都是无色的
        else if(g[_x][_y]==g[x][y]&&g[_x][_y]&&g[x][y]) dfs(_x,_y,res,0);//移动到同颜色方块
        else if((g[_x][_y]!=g[x][y])&&g[_x][_y]&&g[x][y]) dfs(_x,_y,res+1,0);//移动到不同颜色方块
        else if(g[x][y]&&!g[_x][_y]&&!col) dfs(_x,_y,res+2,g[x][y]);//施展魔法
        else if(!g[x][y]&&g[_x][_y]&&col)//从魔法块走到颜色块 
        {
            if(col!=g[_x][_y]) dfs(_x,_y,res+1,0);
            else dfs(_x,_y,res,0);
        }
    }
}
int X,Y,T;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&X,&Y,&T);
        g[X][Y]=++T;//这里把T的值+1,避免和0重复。
    }
    memset(dis,0x3f,sizeof dis);//赋极大值
    dfs(1,1,0,1);
    if(dis[n][n]==0x3f3f3f3f) dis[n][n]=-1;//未更新就说明没找到
        printf("%d",dis[n][n]);
    return 0;
}

bfs

#include<iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
const int N=1e3+100;
struct node
{
    int x,y,col,w,flag;
    bool operator<(const node & t)const{
        return w>t.w;
    }
    node(){};
    node(int _x,int _y,int _col,int _w,int _flag)
    {
        x=_x;
        y=_y;
        col=_col;
        w=_w;
        flag = _flag;
    }
};
int n,m,g[N][N],dis[N][N];
int st[N][N];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        c++;
        g[a][b]=c;
    }
    memset(dis,0x3f3f3f3f,sizeof dis);
    priority_queue<node>q;
    q.push(node(1,1,g[1][1],0,1));
    st[1][1]=1;
    while(q.size())
    {
        node t=q.top();
        q.pop();
        int x=t.x,y=t.y,col=t.col,w=t.w;
        if(x==n && y==n)
        {
            cout<<dis[n][n]<<endl;
            return 0;
        }
        for(int i=0;i<4;i++)
        {
            int _x=x+dx[i],_y=y+dy[i];

            if(st[_x][_y]) continue;
            if(_x<1 || _x>m||_y<1 || _y>m) continue;
            if(!g[x][y] && !g[_x][_y]) continue;
            else if(g[x][y] &&  !g[_x][_y] && t.flag == 1)
            {
                if(dis[_x][_y]>w+2)
                {
                    dis[_x][_y]=w+2;
                    q.push(node(_x,_y,t.col,w+2,0));
                    st[_x][_y]=1;
                }
            }
            else if(g[x][y] &&  g[_x][_y])
            {
                if(g[_x][_y] == col)
                {
                    if(dis[_x][_y] > w)
                    {
                        dis[_x][_y]=w;
                        q.push(node(_x,_y,g[_x][_y],w,1));
                        st[_x][_y]=1;
                    }
                }
                else if(g[_x][_y] != col)
                {
                    if(dis[_x][_y] > w+1)
                    {
                        dis[_x][_y]=w+1;
                        q.push(node(_x,_y,g[_x][_y],w+1,1));
                        st[_x][_y]=1;
                    }
                }
                
            }
            else if(!g[x][y] && g[_x][_y] && t.flag == 0)
            {
                if(t.col == g[_x][_y])
                {
                    if(dis[_x][_y] > w)
                    {
                        dis[_x][_y]=w;
                        q.push(node(_x,_y,g[_x][_y],w,1));
                        st[_x][_y]=1;
                    }
                }
                if(t.col != g[_x][_y])
                {
                    if(dis[_x][_y] > w+1)
                    {
                        dis[_x][_y]=w+1;
                        q.push(node(_x,_y,g[_x][_y],w+1,1));
                        st[_x][_y]=1;
                    }
                }
            }
        }
    }
    cout<<"-1"<<endl;
    return 0;
}







评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值