棋盘游戏 BFS WA,DFS AC (原以为会超时)

 

 

bfs:

#include<bits/stdc++.h>
using namespace std;
/*
    有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,
    请找出一个从起始位置到终止位置代价最小的路径:
    1、只能沿上下左右四个方向移动     
    2、总代价是没走一步的代价之和     
    3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积     
    4、初始状态为1     每走一步,状态按如下公式变化:(走这步的代价%4)+1。
*/

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

void get_cost(vector<vector<int>>&cost,vector<vector<int>>&board,int start[],int end[]){
    vector<vector<int>>visted(6,vector<int>(6,0));
    queue<pair<int,int>>q;
    int tx,ty,bx,by;
    q.push(make_pair(start[0],start[1]));
    while(!q.empty())
    {
        auto pos = q.front();
        q.pop();
        bx=pos.first;by=pos.second;
        visted[bx][by]=1;
        for(int i=0;i<4;i++)//把四周未访问过且未越界的格点入队
        {
            tx=bx+dx[i];ty=by+dy[i];
            if(visted[tx][ty]!=1&&tx>=0&&ty>=0&&tx<=5&&ty<=5)
            {
                q.push(make_pair(tx,ty));
                cost[tx][ty]=min(board[bx][by]*board[tx][ty],cost[tx][ty]);
                board[tx][ty]=cost[tx][ty]%4+1;
            }
        }
    }
    return ;
}

void bfs(vector<vector<int>>&cost,vector<vector<int>>&dp,int start[],int end[]){
        vector<vector<int>>visted(6,vector<int>(6,0));
        
        queue<pair<int,int>>q;
        int tx,ty,bx,by;
        q.push(make_pair(start[0],start[1]));
        while(!q.empty())
        {
            auto pos = q.front();
            q.pop();
            bx=pos.first;by=pos.second;
            visted[bx][by]=1;
            int tmpcost=1000;
            for(int i=0;i<4;i++)//把四周未访问过且未越界的格点入队
            {
                tx=bx+dx[i];ty=by+dy[i];
                if(visted[tx][ty]!=1&&tx>=0&&ty>=0&&tx<=5&&ty<=5)
                {
                    q.push(make_pair(tx,ty));
                    dp[tx][ty]=min(dp[bx][by]+cost[tx][ty],dp[tx][ty]);
                }
            }
            //cout<<tmpcost<<endl;
            //price+=tmpcost;
    }
    return ;
}


int main(){
    //显然是图的遍历,考虑广度优先搜索
    //单源最小路径
    
    vector<vector<int>>board(6,vector<int>(6,1));
    int init;
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++){
            cin>>init;
            board[i][j]=init;
        }
    }
    
    int x,y;
    int start[2]={0,0};cin>>x>>y;start[0]=x;start[1]=y;
    int end[2]={0,0};cin>>x>>y;end[0]=x;end[1]=y;
    

    
    vector<vector<int>>cost(6,vector<int>(6,1000));
    vector<vector<int>>dp(6,vector<int>(6,10000));
    dp[start[0]][start[1]]=0;
    cost[start[0]][start[1]]=0;
    
    //获得每一步的最小代价
    get_cost(cost,board,start,end);
    //单源最小路径,获得最终代价
    bfs(cost,dp,start,end);
    
    //cout<<cost[1][1]<<" "<<board[1][1]<<endl;
    //上下左右四个方向
    
    //总代价
    
    //cost=borad(a,b)*board(c,d);board(c,d)=cost%4+1;price+=cost;
    //cout<<cost[5][4]<<" "<<cost[5][3]<<" ";
    cout<<board[5][4]<<" "<<board[5][3]<<" ";
    cout<<board[0][0]<<" "<<board[5][5]<<" ";
    cout<<dp[end[0]][end[1]];
    return 0;
}

dfs: dfs内的state判断,

int tmp=state*board[tx][ty];

一定要用state,不能用board[bx][by]*board[tx][ty];

比如初始状态为1,但是有的矩阵出发点的borad不为1

即使出发点唯一,由于dfs会回溯,并没有更改board矩阵,所以出发点的board并不是状态

 

#include<bits/stdc++.h>
using namespace std;

int sx,sy,ex,ey;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int price=INT_MAX;

vector<vector<int>>board(6,vector<int>(6,1));
vector<vector<int>>visted(6,vector<int>(6,0));


void dfs(int bx,int by,int cost,int state){

            int tx,ty;
            //visted[bx][by]=1;
            if(bx==ex&&by==ey)
            {
                price=min(price,cost);
                //cout<<price;
                return;
            }
    
            for(int i=0;i<4;i++)//把四周未访问过且未越界的格点入队
            {
                tx=bx+dx[i];ty=by+dy[i];
                if(visted[tx][ty]!=1&&tx>=0&&ty>=0&&tx<=5&&ty<=5)
                {   
                    int tmp=state*board[tx][ty];
                    visted[tx][ty]=1;
                    dfs(tx,ty,cost+tmp,tmp%4+1);
                    visted[tx][ty]=0;
                }
            }
    }




int main(){
    //显然是图的遍历,考虑广度优先搜索
    //单源最小路径
    

    int init;
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++){
            cin>>init;
            board[i][j]=init;
        }
    }
    
    cin>>sx>>sy>>ex>>ey;
    int state=board[sx][sy];
    dfs(sx,sy,0,1);
     //cout<<start[0]<<" "<<start[1]<<" "<<endpos[0]<<" "<<endpos[1]<<endl;
  
    cout<<price;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值