搜索搜索搜索!
每次把一块积木移动一步,而且每块积木内部的相对位置是不变的,那么每次只要记录积木任意一点的位置表示状态即可.为了方便,我们可以设为每个积木包围块的左上角的点.
如何实现?
一种想法是暴搜!可惜T了…
暴搜优化一下来个迭代加深,每次设定一个步数,可惜还是T了.
由于问题为”最小步数” ,我开始想广搜.可是如何判重?积木位置可以随意移动,状态最多为(30*30)3,数组开不了.后来发现:积木的具体位置是不重要的,也就是说,如果三个积木的相对位置不变,在图上的任何一个位置都是相同的,那么我们只要记录第2,3块积木相对于第1块积木的位置就好了.判重问题解决了,这道题也就解决了.
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
const int M=10;
const int N=3;
const int P=30;
int rx[]={1,0,-1,0},ry[]={0,1,0,-1};
int mp[N][M][M],px[N],py[N],n[N],l[N],w[N],mark[P*2][P*2][P*2][P*2],tx[M*M],ty[M*M];//mp[i][j][k]表示第i块积木相对于包围块左上角为j,k的位置有没有积木,l,w分别表示块的长,宽.mark用来判重,
struct node{
int step;
int nx[3],ny[3];
};
queue<node>Q;
bool finish(){
for(int i=0;i<3;i++){// 判断三个块是否重叠
int ax=px[i],ay=py[i];
int bx=ax+l[i],by=ay+w[i],ok=1;
for(int j=i+1;j<3;j++){//r任意两个快之间不重叠
int cx=px[j],cy=py[j];
int dx=cx+l[j],dy=cy+w[j];
if(!(dx<=ax||cy>=by||cx>=bx||dy<=ay))return false;
}
}
return true;
}
bool chk(int lay,int yix,int step){
int i,j,k,X=px[0],Y=py[0];
int a=px[1]-X+P,b=py[1]-Y+P,c=px[2]-X+P,d=py[2]-Y+P;
if(mark[a][b][c][d])return false;
mark[a][b][c][d]=1;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(i==j)continue;
for(k=0;k<l[i];k++){
for(int p=0;p<w[i];p++){
if(!mp[i][k][p])continue;
int x=k+px[i]-px[j],y=p+py[i]-py[j];
if(x<0||y<0||x>=l[j]||y>=w[j]||!mp[j][x][y])continue;
return false;
}
}
}
}
return true;
}
int main(){
int i,j,k,ans=-1;
for(i=0;i<3;i++)scanf("%d",&n[i]);
for(i=0;i<3;i++){
int mix=10,mxx=-1,miy=10,mxy=-1;
for(j=0;j<n[i];j++){
scanf("%d %d",&tx[j],&ty[j]);
int a=tx[j],b=ty[j];
mix=min(mix,a);
mxx=max(mxx,a);
miy=min(miy,b);
mxy=max(mxy,b);
}
px[i]=mix;
py[i]=miy;
l[i]=mxx-mix+1;
w[i]=mxy-miy+1;
for(j=0;j<n[i];j++){
int a=tx[j]-px[i],b=ty[j]-py[i];
mp[i][a][b]=1;
}
}
if(finish()){puts("1");return 0;}
else {
node tmp;
for(i=0;i<N;i++){
tmp.nx[i]=px[i];
tmp.ny[i]=py[i];
}
tmp.step=0;
Q.push(tmp) ;
}
while(!Q.empty()){
node tmp=Q.front();Q.pop();
for(i=0;i<N;i++){
px[i]=tmp.nx[i];
py[i]=tmp.ny[i];
}
if(finish()){
ans=tmp.step;break;
}
for(i=0;i<N;i++){
for(k=0;k<4;k++){
px[i]+=rx[k],py[i]+=ry[k];
if(px[i]<-10||px[i]>20||py[i]<-10||py[i]>20){
px[i]-=rx[k],py[i]-=ry[k];continue;
}
if(chk(i,k,tmp.step)){
node nex=tmp;;
nex.nx[i]=px[i];
nex.ny[i]=py[i];
nex.step=tmp.step+1;
Q.push(nex);
}
px[i]-=rx[k];
py[i]-=ry[k];
}
}
}
printf("%d\n",(ans!=-1));
return 0;
}