棋盘棋盘棋盘
题目大意:
有一个M*M的棋盘,要从(1,1)到(m,m),中间有n个有颜色的格子,只能踩在有颜色的格子上,跳到不同颜色的格子要花费1元,可以将前方没颜色的格子变成自己要的格子,但要花费2元(走过去还要按上述规则花钱),走出变色出来的格子后,这个格子会变回无颜色,当棋盘上有变色出来的格子时,无法再变色,从(1,1)到(m,m)最少花多少钱?如果走不到,输出-1
解题方法:
这题我们可以用深搜,四个个数x,y,money,p,分别为行,列,用的钱,又没有变过色,在按照提议把每一种走法套进去,还要用一个a[i][j]来记录到(i,j)花费的钱最少是多少,当大于或等于这个数时退出,否则更新a
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int n,ans,m,a[110][110],color[110][110];
const int dx[4]={1,0,-1,0};//四个方向
const int dy[4]={0,1,0,-1};//四个方向
void dfs(int x,int y,int money,int p)
{int o;if ((x==n)&&(y==n))//看看是否到结果{ans=min(ans,money);//求最小的return;}if (a[x][y]<=money) return;//剪枝else a[x][y]=money;//替换if (money>ans) return;//剪枝for (int i=0;i<4;i++)if ((x+dx[i]>0)&&(x+dx[i]<=n)&&(y+dy[i]>0)&&(y+dy[i]<=n))//看看是否出界{if (color[x][y]==color[x+dx[i]][y+dy[i]])//颜色相同{o=color[x][y];//记录if (p) color[x][y]=0;//如果变过色,要变回去dfs(x+dx[i],y+dy[i],money,0);//用加moneycolor[x][y]=o;//再变回来}else if(color[x+dx[i]][y+dy[i]])//有颜色{o=color[x][y];//同上if (p) color[x][y]=0;dfs(x+dx[i],y+dy[i],money+1,0);//money+1color[x][y]=o;}else if(!p)//要没变过{color[x+dx[i]][y+dy[i]]=color[x][y];//不需要考虑变哪种,如果下一步给钱的反过来还是要给钱,不用给就不用给dfs(x+dx[i],y+dy[i],money+2,1);//money+2color[x+dx[i]][y+dy[i]]=0;//清零}}
}
int main()
{memset(a,127/3,sizeof(a));//因为要求最小的ans=a[0][0];//直接复制过去scanf("%d%d",&n,&m);int x,y,c;for (int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&c);color[x][y]=c+1;//要加1才能避免0的出现}dfs(1,1,0,0);if (ans==a[0][0]) ans=-1;printf("%d",ans);
}