poj 1324-Holedox Moving-状態圧縮+BFS
4069 ワード
素朴で暴力的な方法でやった...
現在のヘビ体と前の部分のヘビ体の位置関係を1つの1 2 3 4で表し、ヘビは最長7であるため、4進数で状態を表すことができ、各ヘビ頭、そのヘビ体は4^7種類の状態がある.
TLEの計算が繰り返されないように、状態圧縮マークが表示された状態で...
他にも地味なBFS...
書き方が挫けている.ステータス配列はboolを開いてから通過します.そうしないとtle
もちろん本題は双方向bfs,A*アルゴリズムも使えます.の
素朴なアルゴリズムに基づいてbitsetで状態を表すと3000 kbの空間が節約され、時間は3.8 sも差がない.
以下は素朴な方法です:3.9 s... 10520kb
現在のヘビ体と前の部分のヘビ体の位置関係を1つの1 2 3 4で表し、ヘビは最長7であるため、4進数で状態を表すことができ、各ヘビ頭、そのヘビ体は4^7種類の状態がある.
TLEの計算が繰り返されないように、状態圧縮マークが表示された状態で...
他にも地味なBFS...
書き方が挫けている.ステータス配列はboolを開いてから通過します.そうしないとtle
もちろん本題は双方向bfs,A*アルゴリズムも使えます.の
素朴なアルゴリズムに基づいてbitsetで状態を表すと3000 kbの空間が節約され、時間は3.8 sも差がない.
以下は素朴な方法です:3.9 s... 10520kb
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
struct node
{
int hx,hy;
int body[8]; //1 2 3 4
int step;
};
int len;
int n,m,l;
queue<node> qq;
int dirx[]={0,0,1,-1}; //you zuo xia shang
int diry[]={1,-1,0,0};
int mp[22][22];
bool state[22][22][1<<14];
int trans(int x,int y) // del_x,del_y
{
if (x==-1&&y==0)
return 1; //shang
if (x==1&&y==0)
return 2; //
if (x==0&&y==-1)
return 3 ; //
if (x==0&&y==1)
return 4; //
}
node move_to(node t,int x,int y) // [X,Y]
{
node res;
int i;
for (i=len;i>1;i--)
{
res.body[i]=t.body[i-1];
}
int dir=trans(t.hx-x,t.hy-y);
res.body[1]=dir;
res.step=t.step+1;
res.hx=x;
res.hy=y;
return res;
}
inline void get_xy(int &tx,int &ty,int dir,int x,int y) //
{
if (dir==1)//
{
tx=x-1;ty=y;
}
if (dir==2)//xia
{
tx=x+1;ty=y;
}
if (dir==3)//zuo
{
tx=x;ty=y-1;
}
if (dir==4)//you
{
tx=x;ty=y+1;
}
return ;
}
void deal_map(node t) //
{
int i;
int lastx,lasty;
for (i=1;i<=len;i++)
{
int tx,ty;
if (i==1)
{
get_xy(tx,ty,t.body[i],t.hx,t.hy);
}
else
{
get_xy(tx,ty,t.body[i],lastx,lasty);
}
lastx=tx;
lasty=ty;
if (mp[tx][ty]==0)
mp[tx][ty]=2;
}
}
void un_deal_map(node t) //
{
int i;
int lastx,lasty;
for (i=1;i<=len;i++)
{
int tx,ty;
if (i==1)
{
get_xy(tx,ty,t.body[i],t.hx,t.hy);
}
else
{
get_xy(tx,ty,t.body[i],lastx,lasty);
}
lastx=tx;
lasty=ty;
if (mp[tx][ty]==2)
mp[tx][ty]=0;
}
}
int get_body_num(node &y) //
{
int i;
int ret=0;
for (i=1;i<=len;i++)
{
// ret+=(y.body[i]-1)* int(pow(4.0,i-1));
ret+=(y.body[i]-1)* 1<<(2*(i-1)) ; //
}
return ret;
}
int main()
{
int cnt=1;
while(scanf("%d%d%d",&n,&m,&l)!=EOF)
{
if (!n&&!m&&!l) break;
while(!qq.empty())
qq.pop();
node tm;
memset(mp,0,sizeof(mp));
memset(state,0,sizeof(state));
int i;
scanf("%d%d",&tm.hx,&tm.hy);
for (i=0;i<=m+1;i++) //lock the board
mp[0][i]=1;
for (i=0;i<=m+1;i++)
mp[n+1][i]=1;
for (i=0;i<=n+1;i++)
mp[i][0]=1;
for (i=0;i<=n+1;i++)
mp[i][m+1]=1;
int xx,yy;
int lastx,lasty;
int delx,dely;
for (i=1;i<=l-1;i++)
{
scanf("%d%d",&xx,&yy);
if (i==1)
{
delx=xx-tm.hx;
dely=yy-tm.hy;
}
else
{
delx=xx-lastx;
dely=yy-lasty;
}
tm.body[i]=trans(delx,dely); //
lastx=xx;
lasty=yy;
}
len=l-1;
int num;
scanf("%d",&num);
for (i=1;i<=num;i++)
{
scanf("%d%d",&xx,&yy);
mp[xx][yy]=1; //
}
////
tm.step=0;
int ret=get_body_num(tm);
state[tm.hx][tm.hy][ret]=true;
qq.push(tm);
int ans=-1;
while(!qq.empty())
{
node t=qq.front();
qq.pop();
if (t.hx==1&&t.hy==1) //
{
ans=t.step;
break;
}
deal_map(t); //
for (i=0;i<4;i++)
{
int x=t.hx+dirx[i];
int y=t.hy+diry[i];
if (mp[x][y]) continue; //
node res=move_to(t,x,y); // res
int ret=get_body_num(res); //
if (state[res.hx][res.hy][ret]==true)
continue;
state[res.hx][res.hy][ret]=true;
qq.push(res);
}
un_deal_map(t); //
}
printf("Case %d: %d
",cnt++,ans);
}
return 0;
}