注意输入:
m表示宽度,n表示高度(m表示列,n表示行)
dfs:
从左上角开始走迷宫,如果走过路径的和为SUM/2,记录走过数字个数
求走过数字的最小值
代码:
#include<iostream>
using namespace std;
const int MAX=15;
int n,m;
int size,sum,now,ans=100;
int map[MAX][MAX];//图作为全局变量
int vis[MAX][MAX];//防止走回头路 ,作为全局变量
int go[][2]={{1,0},{0,1},{-1,0},{0,-1}};//方向数组
void dfs(int x,int y)
{
//走第一步
vis[x][y]=1;
now+=map[x][y];
size++;
if(size>=ans)return ;//剪枝:当走的格子数已经大于前面的最小数量就不必再继续搜索
if(now*2==sum)
{
ans=min(ans,size);
return ;
}
for(int i=0;i<4;i++)//往四个方向走以寻求可以剪的地方
{
int new_x=x+go[i][0],new_y=y+go[i][1];
if(vis[new_x][new_y]==0 && new_x>=1 && new_x<=n
&& new_y>=1 && new_y<=m)
{
dfs(new_x,new_y);
vis[new_x][new_y]=0; //回溯的时候需要将已访问过的点还原为未访问
size--; //同时将用于标记格子数的变量减1
now-=map[new_x][new_y]; //以及把用于记录当前访问格子总和的变量还原
}
}
}
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
sum+=map[i][j];
}
}
dfs(1,1);
if(ans==100)
cout<<0<<endl;
else
cout<<ans<<endl;
return 0;
}
参考:【蓝桥杯】历届试题 剪格子(深度优先搜索dfs、广度优先搜索bfs)_the_ZED的博客