zoj1005 BFS+路径输出
这道题一开始就想用搜索做,想的实际上也没错,因为要输出路径,所以我一开始使用了dfs。但发现深搜就会沿着一条路走到底,而我们只能判断它是否达到了目标状态。如果它不到达目标状态可能会无限循环下去。所以转而用广搜去做这道题,但广搜要如何保存路径呢?于是我想到了用结构体struct加STL里的容器进行存储路径,这里我使用了队列.题中有六种操作,但在不同情况下有着不同的操作不能进行,这才能保证题目能在两秒内完成。而我在输入后没有加!=EOF而找了很久BUG,哭了。。。。;
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
int A,B,a,b,goal;
int vis[1000][1000];
struct point{//记录当时a,b的值,num记录进行的操作
int a;
int b;
int num;
};
struct points{//记录路径
queue<point> r;
};
bool change(int n){//对六种的操作进行定义,有多种情况可以排除,减少运行时间
if(n==0){
if(a!=0){
return false;
}
a=A;
}
else if(n==1){
if(b!=0){
return false;
}
b=B;
}
else if(n==2){
if(a!=A){
return false;
}
a=0;
}
else if(n==3){
if(b!=B){
return false;
}
b=0;
}
else if(n==4){
if(a==0||b==B||(a==A&&b==B)){
return false;
}
b+=a;
if(b>B){
a=b-B;
b=B;
}
else{
a=0;
}
}
else{
if(b==0||a==A||(a==A&&b==B)){
return false;
}
a+=b;
if(a>A){
b=a-A;
a=A;
}
else{
b=0;
}
}
return true;
}
void input(int n){
if(n==0){
printf("fill A\n");
}
else if(n==1){
printf("fill B\n");
}
else if(n==2){
printf("empty A\n");
}
else if(n==3){
printf("empty B\n");
}
else if(n==4){
printf("pour A B\n");
}
else{
printf("pour B A\n");
}
}
void bfs(){
point tempp;
points tempq;
queue<points> p;
vis[0][0]=1;
for(int i=0;i<6;i++){
a=0;b=0;
if(change(i)){
tempp.a=a;tempp.b=b;tempp.num=i;
vis[a][b]=1;//记录a,b这个状态已经经历过,下次遇到这种情况说明存在循环,不是最短路径,直接弹出
tempq.r.push(tempp);
p.push(tempq);
tempq.r.pop();
}
}
while(!p.empty()){
tempq=p.front();
tempp=tempq.r.back();
p.pop();
if(tempp.b==goal){
while(!tempq.r.empty()){
tempp=tempq.r.front();
input(tempp.num);
tempq.r.pop();
}
printf("success\n");
return;
}
point tq=tempq.r.back();
points ts=tempq;
for(int i=0;i<6;i++){
tempp=tq;
tempq=ts;
a=tempp.a;b=tempp.b;
if(change(i)){
point tp;
tp.a=a;tp.b=b;tp.num=i;
if(vis[a][b]!=1){
vis[a][b]=1;
tempq.r.push(tp);
p.push(tempq);
}
}
}
}
}
int main(){
while(scanf("%d %d %d",&A,&B,&goal)!=EOF){
memset(vis,0,sizeof(vis));//数组初始化
bfs();
}
return 0;
}