题目意思就是一个冰壶,要从起点到达终点,你推他一把,他就沿着直线开始滑行,直到撞到一块石头,撞到石头冰壶停止,石头也会消失。但冰壶不会取代那个石头的位置,而是在原来碰撞的位置,问你10次之内能不能到达终点。
用dfs+回溯的方法暴力去搜,顺带剪枝,如果答案大于10了,就不用搜了,这个一定要剪,否则TLE。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define INT_MAX 1<<30
#define debug cout<<xixi.time<<j<<endl;
int w,h;int sx,sy;
char maze[21][21];
int ex,ey;bool flag;
bool check;
int ans;int dir;
struct wode
{
int x, y;
int time;
};
bool can_not(int x, int y)
{
if(x<0||x>=h||y>=w||y<0
||maze[x][y]==1) return 1;
return 0;
}
void dfs(wode xx)
{
int s,t;
if(can_not(xx.x-1,xx.y)
&&can_not(xx.x,xx.y-1)
&&can_not(xx.x+1, xx.y)
&&can_not(xx.x,xx.y+1)) return;
for(int j = 1;j<21;j++)
{
// if(check == 1) break;
s = xx.x;
t = xx.y+j;
wode xixi;
if(maze[s][t] == 1&&abs(j)==1)
break;
xixi.time = xx.time;
xixi.x=s;
xixi.y=t;
if(s==ex&&t==ey)
{
ans = min(ans, xixi.time);
// debug
break;
}
if(!(s>=0&&s<h&&t>=0&&t<w)) break;
if(s>=0&&s<h&&t>=0&&t<w
&&maze[s][t] == 1&&abs(j)!=1)
{
maze[s][t] = 0;
xixi.x-=0;
xixi.y-=1;
if(xixi.x==ex&&xixi.y==ey)
{
ans = min(ans, xixi.time);
return;
}
xixi.time++;
if(xixi.time>9)
{
maze[s][t] = 1;
break;
}
dfs(xixi);
maze[s][t] = 1;
break;
}
}
for(int j = 1;j<21 ;j++)
{
// if(check == 1) break;
s = xx.x;
t = xx.y-j;
if(maze[s][t] == 1&&abs(j)==1)
break;
wode xixi;
xixi.time = xx.time;
xixi.x=s;
xixi.y=t;
if(s==ex&&t==ey)
{
ans = min(ans, xixi.time);
break;
}
if(!(s>=0&&s<h&&t>=0&&t<w)) break;
if(s>=0&&s<h&&t>=0&&t<w
&&maze[s][t] == 1&&abs(j)!=1)
{
maze[s][t] = 0;
xixi.x-=0;
xixi.y+=1;
if(xixi.x==ex&&xixi.y==ey
)
{
ans = min(ans, xixi.time);
return;
}
xixi.time++;
if(xixi.time>9)
{
maze[s][t] = 1;
break;
}
dfs(xixi);
maze[s][t] = 1;
break;
}
}
for(int j = 1;j<21 ;j++)
{
// if(check == 1) break;
s = xx.x+j;
t = xx.y;
if(maze[s][t] == 1&&abs(j)==1)
break;
wode xixi;
xixi.time = xx.time;
xixi.x=s;
xixi.y=t;
if(s==ex&&t==ey)
{
ans = min(ans, xixi.time);
break;
}
if(!(s>=0&&s<h&&t>=0&&t<w)) break;
if(s>=0&&s<h&&t>=0&&t<w
&&maze[s][t] == 1&&abs(j)!=1)
{
maze[s][t] = 0;
xixi.x-=1;
xixi.y-=0;
if(xixi.x==ex&&xixi.y==ey
)
{
ans = min(ans, xixi.time);
return;
}
xixi.time++;
if(xixi.time>9)
{
maze[s][t] = 1;
break;
}
dfs(xixi);
maze[s][t] = 1;
break;
}
}
for(int j = 1;j<21 ;j++)
{
// if(check == 1) break;
s = xx.x-j;
t = xx.y;
if(maze[s][t] == 1&&abs(j)==1)
break;
wode xixi;
xixi.time = xx.time;
xixi.x=s;
xixi.y=t;
if(s==ex&&t==ey)
{
ans = min(ans, xixi.time);
break;
}
if(!(s>=0&&s<h&&t>=0&&t<w)) break;
if(s>=0&&s<h&&t>=0&&t<w
&&maze[s][t] == 1&&abs(j)!=1)
{
maze[s][t] = 0;
xixi.x+=1;
xixi.y-=0;
if(xixi.x==ex&&xixi.y==ey
)
{
ans = min(ans, xixi.time);
return;
}
xixi.time++;
if(xixi.time>9)
{
maze[s][t] = 1;
break;
}
dfs(xixi);
maze[s][t] = 1;
break;
}
}
}
int main()
{
while(~scanf("%d%d",&w, &h), w, h)
{
for(int i = 0; i < h; i++)
for(int j = 0; j < w; j++)
{
scanf("%d", &maze[i][j]);
if(maze[i][j] == 2)
sx = i,sy = j;
else if(maze[i][j]==3)
ex = i,ey = j;
}
wode mimi;
mimi.time=0;
mimi.x=sx;
mimi.y=sy;dir = 0;
flag = 0; ans = INT_MAX;
dfs(mimi);
if(ans > 9)
puts("-1");
else printf("%d\n", ans+1);
}
}