题目地址: http://poj.org/problem?id=1324

优先队列---A*的估价函数不能为蛇头到(1,1)的距离,这样会出错。

看了discuss,有大神说这题A*的估价函数为BFS (0,0)到各点的花费在乘上10 ,但是还是不清楚,希望知道的可以给我留个言,谢谢了。

思路:

用0,1,2,3表示方向,这样就可以用四进制状态压缩了。

总共需要3+3*4^1+……3*4^6.

推荐大家能不用STL就不用STL,太浪费时间了。

下面是用STL超时代码和用数组模拟AC代码。

超时代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std; typedef long long LL;
const int N=21;
const LL II=1000000007; int n,m,L;
int maps[N][N];//0代表空,1代表蛇身体,2代表石头
bool vis[N][N][17000];//状态压缩
int t[4][2]={0,-1,1,0,0,1,-1,0}; struct xh
{
int step;
int po[11][2];
}w,e; int location(int px,int py,int nx,int ny)//求两个节点的相对位置
{
if(px==nx)
{
if(py>ny)
return 0;
else
return 1;
}
else
{
if(px>nx)
return 2;
else
return 3;
}
} int gethash(int B[][2])
{//得到状态
int s=0;
for(int i=0;i<L-1;i++)
s=s*4+location(B[i][0],B[i][1],B[i+1][0],B[i+1][1]);
return s;
} bool inmap(int x,int y,xh a)
{
if(!(x>=1&&x<=n&&y>=1&&y<=m))
return false;
if(maps[x][y]==2)
return false;
for(int i=0;i<L;i++)//蛇头和蛇尾相连也不行的
if(x==a.po[i][0]&&y==a.po[i][1])//判断是否这一步为蛇身
return false;
return true;
} void bfs()
{
int i,j,hash,x,y;
w.step=0;
hash=gethash(w.po);
x=w.po[0][0]; y=w.po[0][1];
vis[x][y][hash]=true;
queue<xh> q;
q.push(w);
if(x==1&&y==1)
{
printf("0\n");
return ;
}
while(!q.empty())
{
e=q.front();
q.pop();
for(i=0;i<4;i++)
{
w=e;
x=w.po[0][0]; y=w.po[0][1];
x+=t[i][0]; y+=t[i][1];
if(!inmap(x,y,w)) continue;
for(j=L-1;j>=1;j--)
{
w.po[j][0]=w.po[j-1][0];
w.po[j][1]=w.po[j-1][1];
}
w.po[0][0]=x; w.po[0][1]=y;
hash=gethash(w.po);
if(vis[x][y][hash]) continue;
vis[x][y][hash]=true;
w.step++;
q.push(w);
if(x==1&&y==1)
{
printf("%d\n",w.step);
return ;
}
}
}
printf("-1\n");
} int main()
{
int i,k,ci=0;
while(scanf("%d%d%d",&n,&m,&L)&&(n+m+L))
{
memset(maps,0,sizeof(maps));
memset(vis,false,sizeof(vis));
for(i=0;i<L;i++)
{
scanf("%d%d",&w.po[i][0],&w.po[i][1]);
}
scanf("%d",&k);
while(k--)
{
int a,b;
scanf("%d%d",&a,&b);
maps[a][b]=2;//石头
}
printf("Case %d: ",++ci);
bfs();
}
return 0;
}

用STL写就超时了,用数组模拟就过了

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std; typedef long long LL;
const int N=21;
const LL II=1000000007; int n,m,L;
int maps[N][N];//0代表空,1代表蛇身体,2代表石头
bool vis[N][N][17000];//状态压缩
int t[4][2]={0,-1,1,0,0,1,-1,0}; struct xh
{
int step;
int po[11][2];
}w,e,q[5000004]; int location(int px,int py,int nx,int ny)//求两个节点的相对位置
{
if(px==nx)
{
if(py>ny)
return 0;
else
return 1;
}
else
{
if(px>nx)
return 2;
else
return 3;
}
} int gethash(int B[][2])
{//得到状态
int s=0;
for(int i=0;i<L-1;i++)
s=s*4+location(B[i][0],B[i][1],B[i+1][0],B[i+1][1]);
return s;
} bool inmap(int x,int y,xh a)
{
if(!(x>=1&&x<=n&&y>=1&&y<=m))
return false;
if(maps[x][y]==2)
return false;
for(int i=0;i<L;i++)//蛇头和蛇尾相连也不行的
if(x==a.po[i][0]&&y==a.po[i][1])//判断是否这一步为蛇身
return false;
return true;
} void bfs()
{
int i,j,hash,x,y,head=0,tail=0;
w.step=0;
hash=gethash(w.po);
x=w.po[0][0]; y=w.po[0][1];
vis[x][y][hash]=true;
q[tail++]=w;
if(x==1&&y==1)
{
printf("0\n");
return ;
}
while(head<tail)
{
e=q[head++];
for(i=0;i<4;i++)
{
w=e;
x=w.po[0][0]; y=w.po[0][1];
x+=t[i][0]; y+=t[i][1];
if(!inmap(x,y,w)) continue;
for(j=L-1;j>=1;j--)
{
w.po[j][0]=w.po[j-1][0];
w.po[j][1]=w.po[j-1][1];
}
w.po[0][0]=x; w.po[0][1]=y;
hash=gethash(w.po);
if(vis[x][y][hash]) continue;
vis[x][y][hash]=true;
w.step++;
q[tail++]=w;
if(x==1&&y==1)
{
printf("%d\n",w.step);
return ;
}
}
}
printf("-1\n");
} int main()
{
int i,k,ci=0;
while(scanf("%d%d%d",&n,&m,&L)&&(n+m+L))
{
memset(maps,0,sizeof(maps));
memset(vis,false,sizeof(vis));
for(i=0;i<L;i++)
{
scanf("%d%d",&w.po[i][0],&w.po[i][1]);
}
scanf("%d",&k);
while(k--)
{
int a,b;
scanf("%d%d",&a,&b);
maps[a][b]=2;//石头
}
printf("Case %d: ",++ci);
bfs();
}
return 0;
}

POJ 1324 Holedox Moving 搜索的更多相关文章

  1. poj 1324 Holedox Moving

    poj 1324 Holedox Moving 题目地址: http://poj.org/problem?id=1324 题意: 给出一个矩阵中,一条贪吃蛇,占据L长度的格子, 另外有些格子是石头, ...

  2. POJ 1324 Holedox Moving (状压BFS)

    POJ 1324 Holedox Moving (状压BFS) Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 18091 Acc ...

  3. POJ - 1324 Holedox Moving (状态压缩+BFS/A*)

    题目链接 有一个n*m(1<=n,m<=20)的网格图,图中有k堵墙和有一条长度为L(L<=8)的蛇,蛇在移动的过程中不能碰到自己的身体.求蛇移动到点(1,1)所需的最小步数. 显然 ...

  4. poj 1324 状态压缩+bfs

    http://poj.org/problem?id=1324 Holedox Moving Time Limit: 5000MS   Memory Limit: 65536K Total Submis ...

  5. poj1324 Holedox Moving

    Holedox Moving Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16980   Accepted: 4039 D ...

  6. POJ.3279 Fliptile (搜索+二进制枚举+开关问题)

    POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...

  7. POJ 1475 Pushing Boxes 搜索- 两重BFS

    题目地址: http://poj.org/problem?id=1475 两重BFS就行了,第一重是搜索箱子,第二重搜索人能不能到达推箱子的地方. AC代码: #include <iostrea ...

  8. poj 3279 Fliptile (简单搜索)

    Fliptile Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16558   Accepted: 6056 Descrip ...

  9. poj 1198 hdu 1401 搜索+剪枝 Solitaire

    写到一半才发现能够用双向搜索4层来写,但已经不愿意改了,干脆暴搜+剪枝水过去算了. 想到一个非常水的剪枝,h函数为  当前点到终点4个点的最短距离加起来除以2.由于最多一步走2格,然后在HDU上T了, ...

随机推荐

  1. java开发异常类型汇总

    1. java.lang.nullpointerexception 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对 ...

  2. android电池充电以及电量检测驱动分析

    前段时间比较烦躁,各种不想学习不想工作,于是休息了几天.这几天又下来任务了--调试充电电路和电池电量检测电路,于是又开始工作,顺便把调试过程记录下来. 平台: cpu        飞思卡尔imx6q ...

  3. Delphi TStream 详细介绍

    Delphi TStream 详细介绍Stream对象,又称流式对象,是TStream.THandleStream.TFileStream.TMemoryStream.TResourceStream和 ...

  4. 八皇后问题详细分析与解答(递归法解答,c#语言描述)

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题.该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或 ...

  5. MySQL 关闭FOREIGN_KEY_CHECKS检查

    SET FOREIGN_KEY_CHECKS=0; truncate table QRTZ_BLOB_TRIGGERS; truncate table QRTZ_CALENDARS; truncate ...

  6. Java NIO实战之聊天室

    在工作之余花了两个星期看完了<Java NIO>.整体来说这本书把NIO写的非常具体,没有过多的废话,讲的都是重点,仅仅是翻译的中文版看的确实吃力.英文水平太低也没办法,总算也坚持看完了. ...

  7. 跟我一起学extjs5(13--运行菜单命令在tabPanel中显示模块)

    跟我一起学extjs5(13--运行菜单命令在tabPanel中显示模块)         上面设计好了一个模块的主界面,以下通过菜单命令的运行来把这个模块增加到主界面其中. 在MainModule. ...

  8. 算法起步之Dijkstra算法

    原文:算法起步之Dijkstra算法 友情提示:转载请注明出处[作者 idlear    博客:http://blog.csdn.net/idlear/article/details/19687579 ...

  9. OC-Protocol实现业务代理

    创建一个Protocol,相当于java的接口,但,有些方法不必实现,例如以下 #import <Foundation/Foundation.h> @protocol MyProtocol ...

  10. SQL_由创建表引出

    ***********************************************声明*************************************************** ...