写起来有点烦...
#include<bits/stdc++.h>
using namespace std;
const int N=105;
const int inf=0x3f3f3f3f;
int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};//四个方向定义
int s[N][N],p[N][N],n,m,flag=0,ans=inf;
void dfs(int x,int y,int cnt,int k)
{
if(cnt>=p[x][y]) return; //如果花费已经大于最小值,则停止搜索
p[x][y]=cnt; //否则更新该点最小值
if(x==n&&y==n)//判断是否到达终点
{
flag=1; //标记为可以到达终点,为主函数判断作铺垫
ans=min(ans,cnt);//更新答案
return;
}
for(int i=0;i<4;i++)//枚举四个方向
{
int tx=x+dir[i][0];//求出往当前方向走的坐标
int ty=y+dir[i][1];
if(tx<1||tx>n||ty<1||ty>n) continue;//判断是否越界
if(s[tx][ty]!=0)//该点有颜色
{
if(s[x][y]==s[tx][ty])
dfs(tx,ty,cnt,0); //如果该点的颜色与上一个经过的点颜色一样则不需要花费魔法
else
dfs(tx,ty,cnt+1,0);//若颜色不一样,则花费+1
}
else
{
if(k==0)//若上一次没有使用魔法
{
s[tx][ty]=s[x][y]; //改变颜色
dfs(tx,ty,cnt+2,1); //花费+2,标记使用了魔法
s[tx][ty]=0; //回溯
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)p[i][j]=inf; //先赋值为一个极大值
for(int i=0;i<m;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
if(c==0)s[x][y]=2; //格子为红色
else s[x][y]=c;//格子为黄色
}
dfs(1,1,0,0);//深搜
if(flag) printf("%d
",ans);
else printf("-1
");
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define inf 0x4f4f4f4f
int f[1001][1001];
int mp[1001][1001];
int ans=inf;
int dx[4]= {-1,0,1,0};
int dy[4]= {0,-1,0,1};
int m,n;
inline void DFS(int x,int y,int tot,bool flag)
{
if(x < 1 || y < 1 || x > n || y > n)
return;
if(!f[x][y]) //如果当前点是无色的,则无效的
return;
if(tot>= mp[x][y]) //如果用的费用大于当前点的
return;
mp[x][y] = tot;
if(x == n && y == n)
{
if(tot < ans)
ans = tot;
return;
}
for(register int i=0; i<=3; ++i)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(f[xx][yy]) //如果是有color的
{
if(f[xx][yy]==f[x][y]) //如果相同的color的
DFS(xx,yy,tot,false);
else
DFS(xx,yy,tot+1,false);
}
else
if(!f[xx][yy]&&!flag)
//如果走到的格子是无color的,且可以使用改色技能
{
f[xx][yy]=f[x][y];
DFS(xx,yy,tot+2,true);
f[xx][yy]=0;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
memset(mp,inf,sizeof(mp));
for(register int i=1; i<=m; i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
f[x][y]=z+1;
}
DFS(1,1,0,false);
if(ans==inf)printf("-1
");
else printf("%d
",ans);
return 0;
}
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int m,n;
int mp[110][110],f[110][110];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y,int z)
{
for(int i=0;i<4;i++)
{
int tx=x+dx[i];
int ty=y+dy[i];
if(tx<1||ty<1||tx>m||ty>m)
continue;
int r=-1;
if(mp[x][y]==mp[tx][ty]&&mp[tx][ty])
//如果是有color的,且同色的
r=0;
else
{
if(mp[tx][ty])
//如果目标点是有色的
r=1;
if(!mp[tx][ty]&&z)
//如果目标点是无色的,且可以采用改色的技能时
r=2;
}
if(r!=-1&&(f[x][y]+r<f[tx][ty]||!f[tx][ty]))
//如果可以移动的话,且移到目标的代价更优,或者目标点从前没走过
{
f[tx][ty]=f[x][y]+r;
if(r==2)
//如果使用了改色的技能的话
{
mp[tx][ty]=mp[x][y];
dfs(tx,ty,0);
//走到(tx,ty)且改色技能失效
mp[tx][ty]=0;
}
else
dfs(tx,ty,1);
}
}
}
int main()
{
f[1][1]=1;
scanf("%d%d",&m,&n);
int x,y,c;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&c);
mp[x][y]=c+1;
//题面居然会0代表红色,于是给所有color加1
}
dfs(1,1,1);
printf("%d",f[m][m]-1);
return 0;
}