#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
using namespace std;
struct node{
int x,y;
}a[4],b[4];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
bool overlap(int x,int y){ //判断当前位置是否有物品
for(int i=0;i<4;i++)
if(a[i].x==x && a[i].y==y)
return false;
return true;
}
bool bound(int x,int y){
return x>=1 && x<=8 && y>=1 && y<=8;
}
//a到最近的b的距离之和
int h(){
int ret= 0 ;
for(int i=0;i<4;i++){
int t = INT_MAX;
for(int j=0;j<4;j++){
t = min(t,abs(a[i].x-b[j].x)+abs(a[i].y-b[j].y));
}
ret += t;
}
return ret;
}
bool dfs(int step,int last){
int t = h();
if(t==0) return true; //已经到达目标状态
t/=2; //最多能超过两个格子
if(step+t>=8 || t>last) return false;
for(int i=0;i<4;i++){ //移动哪个a
for(int j=0;j<4;j++){ //移动的方向,如何进一步加入跳跃的操作?
int xx = a[i].x+dx[j];
int yy = a[i].y+dy[j];
if(bound(xx,yy)){ //首先判断是否越界
if(overlap(xx,yy)){ //若不重叠
a[i].x += dx[j];
a[i].y += dy[j];
if(dfs(step+1,t))
return true;
a[i].x -= dx[j];
a[i].y -= dy[j];
}//重叠
else if(bound(a[i].x+2*dx[j],a[i].y+2*dy[j]) && overlap(a[i].x+2*dx[j],a[i].y+2*dy[j])){
a[i].x += 2*dx[j];
a[i].y += 2*dy[j];
if(dfs(step+1,t))
return true;
a[i].x -= 2*dx[j];
a[i].y -= 2*dy[j];
}
}
}
}
return false;
}
int main(){
while(scanf("%d%d",&a[0].x,&a[0].y)!=EOF){
for(int i=1;i<4;i++)
scanf("%d%d",&a[i].x,&a[i].y);
for(int i=0;i<4;i++)
scanf("%d%d",&b[i].x,&b[i].y);
if(dfs(0,INT_MAX))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
HDU 1401 dfs+剪枝
最新推荐文章于 2021-10-21 18:26:48 发布