POJ 1324 Holedox Moving(我已经努力了。。)
参考了:
poj 1324 简化的贪吃蛇
#include <iostream>
#include <string.h>
#include <string>
#include <cmath>
#include <queue>
#define INF 1999999999
using namespace std;
struct SNote
{
int len;
int SnakeX[8];//蛇 结点 和 位置 0号是头
int SnakeY[8];
int spa;
int deepth;
};
struct poi
{
int x;
int y;
int deepth;
}P;
int MAXss;
int MINss;
int Map[22][22];
int vis[21][21][16400];
queue<SNote> q;
int tovis(SNote sn)
{
string msg;
for(int i=0;i<sn.len-1;i++)
{
if(sn.SnakeX+1==sn.SnakeX[i+1]&&sn.SnakeY==sn.SnakeY[i+1])// shang
{
msg+="10";
}
else if(sn.SnakeX-1==sn.SnakeX[i+1]&&sn.SnakeY==sn.SnakeY[i+1])//xia
{
msg+="11";
}
else if(sn.SnakeY-1==sn.SnakeY[i+1]&&sn.SnakeX==sn.SnakeX[i+1])//zuo
{
msg+="00";
}
else if(sn.SnakeY+1==sn.SnakeY[i+1]&&sn.SnakeX==sn.SnakeX[i+1])//you
{
msg+="01";
}
}
// cout<<msg<<endl;
int sum=0;
for(int i=0;i<msg.length();i++)
{
if(msg=='1')
sum+=pow(2,i);
}
if(vis[sn.SnakeX[0]][sn.SnakeY[0]][sum]==0)
{
vis[sn.SnakeX[0]][sn.SnakeY[0]][sum]=1;
return 1;
}
else return 0;
}
int _bfs()
{
SNote b;
while(!q.empty())
{
b=q.front();
q.pop();
int m[22][22];
for(int i=0;i<22;i++)
for(int j=0;j<22;j++)
m[j]=Map[j];
SNote a=b;
for(int i=0;i<a.len;i++)
{
if(i==0)
m[b.SnakeX][b.SnakeY]=3;
else
m[b.SnakeX][b.SnakeY]=2;
}
if(m[1][1]==3)
{
return b.deepth;
}
else
{
//go up
a=b;
if(m[a.SnakeX[0]-1][a.SnakeY[0]]==0&&(a.deepth+a.SnakeX[0]-1+a.SnakeY[0]-2)<=MAXss)
{
int ac,bc;
ac=a.SnakeX[0]; bc=a.SnakeY[0];
for(int i=1;i<a.len;i++)
{
swap(ac,a.SnakeX);
swap(bc,a.SnakeY);
}
a.SnakeX[0]=a.SnakeX[0]-1;
if(tovis(a))
{
// cout<<"可以向up移动"<<endl;
a.deepth=b.deepth+1;
q.push(a);
}
else ;
}
//go down
a=b;
if(m[a.SnakeX[0]+1][a.SnakeY[0]]==0&&(a.deepth+a.SnakeX[0]+1+a.SnakeY[0]-2)<=MAXss)
{
int ac,bc;
ac=a.SnakeX[0]; bc=a.SnakeY[0];
for(int i=1;i<a.len;i++)
{
swap(ac,a.SnakeX);
swap(bc,a.SnakeY);
}
a.SnakeX[0]=a.SnakeX[0]+1;
if(tovis(a))
{
// cout<<"可以向down移动"<<endl;
a.deepth=b.deepth+1;
q.push(a);
}
else ;
}
//go right
a=b;
if(m[a.SnakeX[0]][a.SnakeY[0]+1]==0&&(a.deepth+a.SnakeX[0]+a.SnakeY[0]-1)<=MAXss)
{
int ac,bc;
ac=a.SnakeX[0]; bc=a.SnakeY[0];
for(int i=1;i<a.len;i++)
{
swap(ac,a.SnakeX);
swap(bc,a.SnakeY);
}
a.SnakeY[0]=a.SnakeY[0]+1;
if(tovis(a))
{
// cout<<"可以向right移动"<<endl;
a.deepth=b.deepth+1;
q.push(a);
}
else ;
}
//go left
a=b;
if(m[a.SnakeX[0]][a.SnakeY[0]-1]==0&&(a.deepth+a.SnakeX[0]+a.SnakeY[0]-3)<=MAXss)
{
int ac,bc;
ac=a.SnakeX[0]; bc=a.SnakeY[0];
for(int i=1;i<a.len;i++)
{
swap(ac,a.SnakeX);
swap(bc,a.SnakeY);
}
a.SnakeY[0]=a.SnakeY[0]-1;
if(tovis(a))
{
// cout<<"可以向left移动"<<endl;
a.deepth=b.deepth+1;
q.push(a);
}
else ;
}
}
}
return -1;
}
int _bfsMAX(SNote &sn)
{
int MMMp[22][22];
int vivis[22][22];
for(int i=0;i<22;i++)
{
for(int j=0;j<22;j++)
vivis[j]=MMMp[j]=Map[j];
}
for(int i=1;i<sn.len;i++)
{
MMMp[sn.SnakeX][sn.SnakeY]=1;
vivis[sn.SnakeX][sn.SnakeY]=1;
}
P.x=sn.SnakeX[0]; P.y=sn.SnakeY[0];
P.deepth=0;
queue<poi> qt;
qt.push(P);
while(!qt.empty())
{
poi K,L;
L=K=qt.front();
qt.pop();
if(K.x==1&&K.y==1)
{
return K.deepth;
}
else
{
K=L;
// go up
if(MMMp[K.x-1][K.y]==0&&vivis[K.x-1][K.y]==0)
{
//cout<<"let's go up\n";
K.x=K.x-1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
K=L;
//go down
if(MMMp[K.x+1][K.y]==0&&vivis[K.x+1][K.y]==0)
{
//cout<<"let's go down\n";
K.x=K.x+1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
K=L;
//go left
if(MMMp[K.x][K.y-1]==0&&vivis[K.x][K.y-1]==0)
{
K.y=K.y-1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
K=L;
//go right
if(MMMp[K.x][K.y+1]==0&&vivis[K.x][K.y+1]==0)
{
K.y=K.y+1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
}
}
return INF;
}
int _bfsNIN(SNote &sn)
{
int MMMp[22][22];
int vivis[22][22];
for(int i=0;i<22;i++)
{
for(int j=0;j<22;j++)
vivis[j]=MMMp[j]=Map[j];
}
P.x=sn.SnakeX[0]; P.y=sn.SnakeY[0];
P.deepth=0;
queue<poi> qt;
qt.push(P);
while(!qt.empty())
{
poi K,L;
L=K=qt.front();
qt.pop();
if(K.x==1&&K.y==1)
{
return K.deepth;
}
else
{
K=L;
// go up
if(MMMp[K.x-1][K.y]==0&&vivis[K.x-1][K.y]==0)
{
//cout<<"let's go up\n";
K.x=K.x-1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
K=L;
//go down
if(MMMp[K.x+1][K.y]==0&&vivis[K.x+1][K.y]==0)
{
//cout<<"let's go down\n";
K.x=K.x+1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
K=L;
//go left
if(MMMp[K.x][K.y-1]==0&&vivis[K.x][K.y-1]==0)
{
K.y=K.y-1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
K=L;
//go right
if(MMMp[K.x][K.y+1]==0&&vivis[K.x][K.y+1]==0)
{
K.y=K.y+1;
vivis[K.x][K.y]=1;
K.deepth=K.deepth+1;
qt.push(K);
}
}
}
return INF;
}
int main()
{
int tot=0;
int m,n,c;
while(cin>>n>>m>>c&&m!=0&&c!=0&&n!=0)
{
SNote sn;
tot++;
memset(Map,0,sizeof(Map));
memset(vis,0,sizeof(vis));
for(int i=0;i<=m+1;i++)
{
Map[0]=1;
Map[n+1]=1;
}
for(int i=0;i<=n+1;i++)
{
Map[0]=1;
Map[m+1]=1;
}
sn.len=c;
for(int i=0;i<c;i++)
{
cin>>sn.SnakeX>>sn.SnakeY;
}
sn.deepth=0;
int k;
cin>>k;
for(int i=0;i<k;i++)
{
int a,b;
cin>>a>>b;
Map[a]=1;
}
q.push(sn);
MAXss=_bfsMAX(sn);
MINss=_bfsNIN(sn);
// cout<<MAXss<<endl;
if(MINss==MAXss) cout<<"Case "<<tot<<": "<<MINss<<endl;
else if(MINss==INF) cout<<"Case "<<tot<<": "<<-1<<endl;
else
cout<<"Case "<<tot<<": "<<_bfs()<<endl;
while(!q.empty())
q.pop();
}
return 0;
}
贴一个可以AC的:(想抄的就去抄吧)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2005
#define inf 1<<28
using namespace std;
int n,m,k;
struct snake
{
int x,y;
} Snake[10],q1[1000000];//记录贪食蛇的坐标
int ans=-1;
struct snakeState
{
snake body[8];
int num;
} q[1000000];//一整条蛇和蛇走的路程
bool Map[21][21];
bool visit[21][21][17000];
int movex[4]= {0,1,0,-1}; //l,d,r,u
int movey[4]= {-1,0,1,0};
bool visit1[21][21];
int move[21][21];
int inmap(snake &x,snake body[])//判断是否可以走这步
{
if(x.x<=0||x.y<=0||x.x>n||x.y>m||Map[x.x][x.y])
return 0;
for(int i=1; i<k; i++)//蛇头与蛇身相撞,则不可以走
if(x.x==body.x&&x.y==body.y)
return 0;
for(int i=k-1; i>0; i--)//如果可以走这步将贪食蛇的位置更新
body=body[i-1];
body[0].x=x.x;//贪食蛇蛇头的新坐标
body[0].y=x.y;
return 1;//返回成功
}
int findmove(snake &a,snake &b)//找出从位置b-a是哪个方向过来的
{
if(a.x==b.x)
{
if(a.y<b.y)
return 0;//返回值与movex,movey的值要匹配
else return 1;
}
else
{
if(a.x>b.x)
return 3;
else return 2;
}
}
void bfs()
{
int i,j;
snakeState a;
for(i=0; i<k; i++)
a.body=Snake;
int num=0,cnt=0;
a.num=0;
int state=0;
for(i=0; i<k-1; i++)
state=4*state+findmove(Snake,Snake[i+1]);//计算贪食蛇的状态(唯一性)根据前一状态走到后一状态的方向计算得出
visit[Snake[0].x][Snake[0].y][state]=1;
q[0]=a;
num++;
while(cnt<num)
{
snakeState temp=q[cnt];
cnt++;
if(temp.body[0].x==1&&temp.body[0].y==1)
{
ans=temp.num;
return ;
}
for(i=0; i<4; i++)
{
snakeState now=temp;
snake now1;
now1.x=temp.body[0].x+movex;
now1.y=temp.body[0].y+movey;
if(!inmap(now1,now.body))//是否可以走
continue;
now.num=temp.num+1;
state=0;
for(j=0; j<k-1; j++)
state=4*state+findmove(now.body[j],now.body[j+1]);//计算当前的状态
if(visit[now.body[0].x][now.body[0].y][state])
continue;
visit[now.body[0].x][now.body[0].y][state]=1;
if(now.body[0].x==1&&now.body[0].y==1)
{
ans=now.num;
return ;
}
q[num]=now;
num++;
}
}
}
void bfs1()//计算min和max
{
int num=0,cnt=0;
q1[num]=Snake[0];
num++;
visit1[Snake[0].x][Snake[0].y]=1;
move[Snake[0].x][Snake[0].y]=1;
while(cnt<num)
{
snake temp=q1[cnt];
cnt++;
if(temp.x==1&&temp.y==1)
{
return ;
}
for(int i=0; i<4; i++)
{
int tx=temp.x+movex;
int ty=temp.y+movey;
if(tx>=1&&ty>=1&&tx<=n&&ty<=m&&!visit1[tx][ty])
{
move[tx][ty]=move[temp.x][temp.y]+1;
if(tx==1&&ty==1)
return ;
visit1[tx][ty]=1;
snake now;
now.x=tx;
now.y=ty;
q1[num]=now;
num++;
}
}
}
}
void show()
{
int i,j;
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
cout<<move[j]<<" ";
cout<<endl;
}
}
int main()
{
int i,j,l,CASE=0;
while(scanf("%d%d%d",&n,&m,&k),n|m|k)
{
memset(Map,0,sizeof(Map));
memset(visit,0,sizeof(visit));
memset(visit1,0,sizeof(visit1));
memset(move,0,sizeof(move));
for(i=0; i<k; i++)
{
scanf("%d%d",&Snake.x,&Snake.y);
}
int kkk,x,y;
ans=-1;
//show();
scanf("%d",&kkk);
while(kkk--)
{
scanf("%d%d",&x,&y);
Map[x][y]=1;
visit1[x][y]=1;
}
bfs1();//第一次BFS只考虑蛇头和stone;
//show();
if(move[1][1]==0)//如果(1,1)不可到达
{
printf("Case %d: -1\n",++CASE);
continue;
}
int min=move[1][1];
memset(move,0,sizeof(move));
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
visit1[j]=Map[j];
}
for(i=1; i<k; i++)//第二次BFS,还要另外将蛇身看成stone
visit1[Snake.x][Snake.y]=1;
bfs1();
int max=move[1][1];
if(min==max)//如果 min和max相等
{
printf("Case %d: %d\n",++CASE,min-1);
continue;
}
bfs();
printf("Case %d: %d\n",++CASE,ans);
}
return 0;
}