您的位置:首页 > 其它

[kuangbin带你飞]专题一 简单搜索 Pots : BFS

2016-10-15 13:28 288 查看
题意:

有两个被子,容量分别是A和B,想得到目标容量C(A、B中任意一个容量是C就行)。

有3个操作:

 1. FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;

 2. DROP(i) empty the pot i to the drain;

 3. POUR(i,j) pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

输出最少步骤,并且回溯操作过程。

题解:

这题是经典的BFS题,难点就是 “回溯操作的过程”。

我是这样做的:我把所有的状态节点从queue pop出来之前,都加到vector里面,保存起来!然后节点cur中有个变量 pre,这个cur.pre表示的是 前一个操作的节点在vector中的下标。其中,节点最多有 100*100=10000个。而状态标记数组可以用f[105][105]来实现。

节点结构:

typedef struct Node{
    int x,y,stp,opt,pre;
}Node;

代码:

1A。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;

int f[105][105];
typedef struct Node{
int x,y,stp,opt,pre;

}Node;

char s[7][10]={
"","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"
};

Node st,en;
int A,B,C,ans;
vector<Node >v;

void operate(int indx,Node *nw){
int tot=nw->x+nw->y;

if(indx==1)//fill(1)
nw->x=A;

if(indx==2)//fill(2)
nw->y=B;

if(indx==3)//drop(1)
nw->x=0;

if(indx==4)//drop(2)
nw->y=0;

if(indx==5){//pour(1,2)
if(tot>=B){
nw->x=tot-B;
nw->y=B;
}else{
nw->x=0;
nw->y=tot;
}
}

if(indx==6){//pour(2,1)
if(tot>=A){
nw->x=A;
nw->y=tot-A;
}else{
nw->x=tot;
nw->y=0;
}
}

}

void print_ans(Node en){
if(en.pre==-1){
//printf("%d %s\n",en.stp,s[en.opt]);
return;
}

Node p= v[en.pre];
print_ans(p);
printf("%s\n",s[en.opt]);
}

int main(int argc, const char * argv[]) {

while(~scanf("%d%d%d",&A,&B,&C)){

st.x=0; st.y=0;
st.opt=-1; st.stp=0;
st.pre=-1;
memset(f,0,sizeof(f));
f[0][0]=1;

queue<Node >Q;
v.clear();
Q.push(st);
ans=-1;

while(!Q.empty()){
Node cur,nw;
cur=Q.front();

//节点存档
v.push_back(cur);

if(cur.x==C || cur.y==C) {
ans=cur.stp;
en=cur;
break;
}

for(int i=1;i<=6;i++)
{
nw=cur;
operate(i,&nw);
if(!f[nw.x][nw.y]){

f[nw.x][nw.y]=1;
nw.stp=cur.stp+1;
nw.opt=i;
nw.pre=(int)v.size()-1;
Q.push(nw);
}
}

Q.pop();
}

if(ans!=-1) {
printf("%d\n",ans);
print_ans(en);
}
else puts("impossible");

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: