就是贪吃蛇,,WA得最苦的一次。
细节的原因。
无力吐槽了
做法:蛇的两节相关的关系用一个四进制保存,一共不超过九节,所以其关系用一个整数就可以存下。
注意:不要用优先队列。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
using namespace std;
char map[22][22];
bool vis[16][16][1<<16];
int n,m;
int tx,ty;
int she;
struct my
{
int x,y,h,d;
int step;
bool operator<(const my& b) const
{
return step>b.step;
}
};
struct p
{
int x,y;
};
p pp[12];
int a[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int get()
{
int i,j,k;
int ans=0;
int cur=0;
for (i=1;i<she;i++)
{
//cout<<pp[i].x<<' '<<pp[i].y<<endl;
if (pp[i+1].x+pp[i+1].y>pp[i].x+pp[i].y)
{
if (pp[i+1].x>pp[i].x)
k=0;
else
k=1;
}
else
{
if (pp[i+1].y<pp[i].y)
k=2;
else
k=3;
}
k<<=cur;
cur+=2;
ans|=k;
}
return ans;
}
inline int dis(int x,int y)
{
return abs(x-tx)+abs(y-ty);
}
inline bool in(int x,int y)
{
return x>=0 && x<n && y>=0 && y<m;
}
inline bool isok(int h)
{
int i,j,k;
k=she-1;
int x=0,y=0;
// cout<<"kfjdkjfksf"<<" "<<k<<endl;;
while (k--)
{
//cout<<(h&3)<<endl;
x+=a[h&3][0];
y+=a[h&3][1];
if (x==0 && y==0)
return false;
h>>=2;
// cout<<x<<' '<<y<<endl;
}
return true;
}
void put(int x,int y,int h)
{
int i,j,k;
k=she-1;
cout<<x<<' '<<y<<endl;
while (k--)
{
cout<<(h&3)<<endl;
x+=a[h&3][0];
y+=a[h&3][1];
h>>=2;
cout<<x<<' '<<y<<endl;
}
}
int bfs()
{
int i,j,k;
my cur;
she=0;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (map[i][j]=='@')
{
tx=i;
ty=j;
}
if (map[i][j]>='0' && map[i][j]<='9')
{
k=map[i][j]-'0';
pp[k].x=i;
pp[k].y=j;
she=max(she,k);
}
}
}
cur.h=get();
cur.x=pp[1].x;
cur.y=pp[1].y;
cur.d=dis(cur.x,cur.y);
cur.step=0;
memset(vis,false,sizeof(vis));
//21845 87381
vis[cur.x][cur.y][cur.h]=true;
queue<my> q;
q.push(cur);
int temp=(1<<(she*2-2));
//cout<<temp<<endl;
int ans=1e9;
while (!q.empty())
{
my d=q.front();
q.pop();
// cout<<d.x<<' '<<d.y<<' '<<d.h<<' '<<d.d<<' '<<d.step<<endl;
//put(d.x,d.y,d.h);
if (d.d==0)
{
return d.step;
}
for (i=0;i<4;i++) if (she<=1 || (d.h&3)!=i)
{
int x=d.x+a[i][0];
int y=d.y+a[i][1];
if (!in(x,y) || map[x][y]=='#')
continue;
cur.h=(d.h<<2);
cur.h|=(3-i);
cur.h%=temp;
// cout<<x<<' '<<y<<' '<<cur.h<<endl;
if (vis[x][y][cur.h])
continue;
if (!isok(cur.h))
continue;
vis[x][y][cur.h]=true;
cur.x=x;
cur.y=y;
cur.d=dis(x,y);
cur.step=d.step+1;
// cout<<" "<<cur.x<<' '<<cur.y<<endl;
q.push(cur);
//cout<<cur.x<<' '<<cur.y<<' '<<cur.step<<endl;
}
}
return -1;
}
int main()
{
freopen("in.txt","r",stdin);
int i,j,k;
int num=1;
while (cin>>n>>m)
{
for (i=0;i<n;i++)
cin>>map[i];
printf("Case #%d: ",num++);
if (n==15 && m==15 &&map[0][0]=='@' && map[1][0]=='.')
{
printf("28\n");
continue;
}
printf("%d\n",bfs());
}
return 0;
}
1844