您的位置:首页 > 其它

USACO1.4.2(The clocks)BFS

2013-02-12 14:25 489 查看
Description

考虑将如此安排在一个 3 x3 行列中的九个时钟:



目标要找一个最小的移动顺序次将所有的指针指向12点。 下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。 选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。 移动方法 受影响的时钟 1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI Example



[但这可能不是正确的方法,请看下面]

Input

第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。 数字的含意和上面第一个例子一样。

Output

单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。 如果有多种方案,输出那种使的连接起来数字最小的方案。(举例来说5 2 4 6 < 9 3 1 1)。

Single Input

9 9 12

6 6 6

6 3 6

Single Output

4 5 8 9

自定义 状态 类型,并定义状态数组,而查找时使用哈希查找表。具体代码如下:

#include<iostream>
#include<cstring>
#define mem(a) memset(a,0,sizeof(a));
using namespace std;
typedef int State[9];//定义“状态”类型
const int MAXN=320000;//定义最大状态
const int MAXSIZE=100003;//哈希表的最大范围
int head[MAXSIZE],fa[MAXN],next[MAXN],move[MAXN];//head为哈希表中的头结点,next为哈希值相同时组成的链表,fa时父节点,move记录变化时所取的值
State st[MAXN];//状态数组,所有状态都保存在这里
const State goal={3,3,3,3,3,3,3,3,3};//目标状态,4个时间3,6,9,12依次转化为0,1,2,3;所以目标状态是9个3
const char mo[9][6]={"abde","abc","bcef","adg","bdefh","cfi","degh","ghi","efhi"};//移动的钟

void shuru()//输入并转化为0,1,2,3
{
mem(head);mem(next);//置0
int i;
for(i=0;i<9;i++){cin>>st[0][i];st[0][i]=st[0][i]/3-1;}
}
int hash(State& s)//定义哈希函数
{
int i,a=0;
for(i=0;i<9;i++)a=a*10+s[i];//随便算,比如把几个数字转化成9位数
return a%MAXSIZE;//确保哈希函数值是不超过表大小的非负正整数
}
bool insert(int a)//尝试插入
{
int h=hash(st[a]);
int u=head[h];
while(u)//从表头开始查找链表
{
if(memcmp(st[u],st[a],sizeof(st[a]))==0)return false;//找到了,插入失败
u=next[u];//顺着链表继续查找
}
next[a]=head[h];//插入到链表中
head[h]=a;
return true;
}
void print(int p)//打印
{
if(!fa[p]){cout<<move[p];return ;}
print(fa[p]);
cout<<" "<<move[p];
}
void bfs()//BFS宽搜
{
int rear=1,front=0;
for(;;)
{
State& s=st[front];
if(memcmp(s,goal,sizeof(goal))==0){print(front);cout<<endl;return ;}//一旦找到就打印并结束搜索
int i;
for(i=0;i<9;i++)//从1到9依次变化
{
State& t=st[rear];
memcpy(&t,&s,sizeof(s));
int len=strlen(mo[i]),j;
for(j=0;j<len;j++)
t[mo[i][j]-'a']=(t[mo[i][j]-'a']+1)%4;
if(insert(rear)){move[rear]=i+1;fa[rear++]=front;}//可以插入,记录并队列尾加1
}
front++;
}
}
int main()
{
shuru();
bfs();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: