思路来源
我自己想的,只是想总结一下QAQ
题意
相当于,扔一个保龄球,
碰到墙就能砸毁墙,并停在墙前一格
碰到终点的洞,就会落下去
问起点到终点,最少需要几格
心得
是个简单dfs,然而debug了好久。
自己得做一遍大一的题,好好巩固一下知识QAQ
嗯,大一学的时候,就是不大懂那个改回去的操作,
if(maze[xx][yy]==1)
{
maze[xx][yy]=0;
dfs(xx-dx[i],yy-dy[i],step+1);
maze[xx][yy]=1;
}
就像拆盒子一样,先给当前盒子标记,再去拆盒子的子盒子,
拆里面子盒子的子盒子(递归)
如果有解,就带着标记,
否则没解,返回时,把该盒子的标记改回来。
不得不说,这题样例很良心,
让我找到了自己所有和样例考虑的不一样的地方。
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <functional>
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const int mod=1e9+7;
const int MOD=998244353;
const double eps=1e-7;
typedef long long ll;
#define vi vector<int>
#define si set<int>
#define pii pair<int,int>
#define pi acos(-1.0)
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define sci(x) scanf("%d",&(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define pri(x) printf("%d",(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int r,c,sx,sy,ex,ey,ans;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
int maze[25][25];
bool check(int xx,int yy)
{
if(xx>=0&&xx<r&&yy>=0&&yy<c)return 1;
return 0;
}
void init()
{
ans=INF;
mem(maze,-1);
}
void dfs(int x,int y,int step)
{
if(step>10)return;
else if(x==ex&&y==ey)
{
ans=min(ans,step);
return;
}
for(int i=0;i<4;++i)
{
int xx=x+dx[i],yy=y+dy[i];
if(check(xx,yy)&&maze[xx][yy]==1)continue;//相邻墙 不行
while(check(xx,yy)&&(maze[xx][yy]==0||maze[xx][yy]==2))xx+=dx[i],yy+=dy[i];
if(!check(xx,yy))continue;
if(maze[xx][yy]==1)
{
maze[xx][yy]=0;
dfs(xx-dx[i],yy-dy[i],step+1);
maze[xx][yy]=1;
}
else if(maze[xx][yy]==3)
{
dfs(xx,yy,step+1);
}
}
}
int main()
{
while(~scanf("%d%d",&c,&r)&&c+r)
{
init();
rep(i,0,r-1)
{
rep(j,0,c-1)
{
sci(maze[i][j]);
if(maze[i][j]==2)sx=i,sy=j;
else if(maze[i][j]==3)ex=i,ey=j;
}
}
dfs(sx,sy,0);
if(ans==INF)ans=-1;
printf("%d\n",ans);
}
return 0;
}