您的位置:首页 > 其它

poj1753解题报告(2):BFS

2015-09-11 21:20 393 查看

摘要:这是第一次学习使用c++STL中的queue,感觉知其然不知其所以然,不过基本用法了解了.很方便,不用自己定义队列ADT了.用0-65535代表所有的状态,首先检测初始状态,因为后面的程序不会检测它.如果不满足,那么就进入循环(BFS),每次出队一个状态,然后进行决策得到下一个状态,然后判断这个状态是否符合条件,如果符合,就直接输出(由于BFS,一定是最小的),否则判断该状态是否已经访问过,如果没有就入队.直到队列为空.

#include "stdafx.h"
#include<string.h>
#include<queue>
#include<iostream>
#include "string.h"
using namespace std;
short Isvisited[65536];
int flip(int state,int index)
{
int i = index/4, j = index%4;
state ^= (1<<index);
if(i!=0)
state ^= 1<<(index-4);
if(i!=3)
state ^= 1<<(index+4);
if(j!=0)
state ^= 1<<(index - 1);
if(j!=3)
state ^= 1<<(index+1);
return state;
}
int main()
{
int currentstate = 0;//定义一个时刻的状态
memset(Isvisited,-1,sizeof(Isvisited));//初始化
queue<int> state;//定义一个关于状态(0-65535)的队列state
char S;
for(int i = 0;i<=15;i++)//输入初始状态
{
cin>>S;
if(S=='b')
currentstate += (1<<i);
}
if(currentstate == 0||currentstate==65535)//初始状态符合条件,因为后面的循环没有考虑初始状态,而是直接出队,考察后面的状态
{
cout<<0<<endl;
return 0;
}
else
{
Isvisited[currentstate] = 0;
state.push(currentstate);//将初始状态入队
while(!state.empty())//只要队列不为空
{
currentstate = state.front();
state.pop();//出队
for(int i = 0;i<=15;i++)//进行广度搜索,遍历该状态下的每一个决策
{
int nextstate;//定义这一次翻转后的状态
nextstate = flip(currentstate,i);//进行翻转
if(nextstate == 0||nextstate == 65535)//翻转后的状态符合条件
{
cout<<Isvisited[currentstate]+1<<endl;
return 0;
}
else if(Isvisited[nextstate]==-1)//没有访问过这个状态
{
state.push(nextstate);//将产生的翻转后的状态入队
Isvisited[nextstate]=Isvisited[currentstate]+1;//该状态由上一个状态的翻转次数加1
}
}//遍历16个决策
}//队列不空
}
cout<<"Impossible"<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: