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;
}