poj3414
题目名称:Pots
题目链接:http://poj.org/problem?id=3414
题意:
给出了两个瓶子的容量A,B, 以及一个目标水量C,
对A、B可以有如下操作:
FILL(i) 将瓶 i 倒满水;
DROP(i) 将瓶 i 倒空;
POUR(i,j) 将瓶 i 的水倒到瓶 j 中,如果瓶 j 满了(或许有些水留在瓶 i ),或者瓶 i 空了,说明都倒到 j 中.
问经过哪几个操作后能使得任意一个瓶子的残余水量为C。若不可能得到则输出impossible
代码如下(直接用stl的queue):
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<queue> using namespace std; const int INF=0x3ffffff; int A,B,C; int ans; bool ok,vis[105][105]; struct Last { int x,y; int lo; }last[105][105]; //保存上一步骤两杯的水量和操作的编号 char dir[6][10]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"}; struct Node { int a,b; int sum; }; queue<Node> q; void print(int a,int b) { if(a!=0||b!=0) { print(last[a][b].x,last[a][b].y); printf("%s\n",dir[last[a][b].lo]); } } void bfs(Node ss) { while(!q.empty()) q.pop(); q.push(ss); while(!q.empty()) { Node now=q.front(); q.pop(); if(now.a==C||now.b==C) { printf("%d\n",now.sum); print(now.a,now.b); return ; } Node tmp; //FILL(1); if(!vis[A][now.b]) { vis[A][now.b]=true; tmp.a=A; tmp.b=now.b; tmp.sum=now.sum+1; last[A][now.b].x=now.a; last[A][now.b].y=now.b; last[A][now.b].lo=0; q.push(tmp); } //FILL(2) if(!vis[now.a][B]) { vis[now.a][B]=true; tmp.a=now.a; tmp.b=B; tmp.sum=now.sum+1; last[now.a][B].x=now.a; last[now.a][B].y=now.b; last[now.a][B].lo=1; q.push(tmp); } //DROP(1); if(!vis[0][now.b]) { vis[0][now.b]=true; tmp.a=0; tmp.b=now.b; tmp.sum=now.sum+1; last[0][now.b].x=now.a; last[0][now.b].y=now.b; last[0][now.b].lo=2; q.push(tmp); } //DROP(2) if(!vis[now.a][0]) { vis[now.a][0]=true; tmp.a=now.a; tmp.b=0; tmp.sum=now.sum+1; last[now.a][0].x=now.a; last[now.a][0].y=now.b; last[now.a][0].lo=3; q.push(tmp); } //POUR(1,2) int w1=min(now.a,B-now.b); if(!vis[now.a-w1][now.b+w1]) { tmp.a=now.a-w1; tmp.b=now.b+w1; tmp.sum=now.sum+1; last[now.a-w1][now.b+w1].x=now.a; last[now.a-w1][now.b+w1].y=now.b; last[now.a-w1][now.b+w1].lo=4; vis[now.a-w1][now.b+w1]=true; q.push(tmp); } //POUR(2,1) int w2=min(A-now.a,now.b); if(!vis[now.a+w2][now.b-w2]) { tmp.a=now.a+w2; tmp.b=now.b-w2; tmp.sum=now.sum+1; last[now.a+w2][now.b-w2].x=now.a; last[now.a+w2][now.b-w2].y=now.b; last[now.a+w2][now.b-w2].lo=5; vis[now.a+w2][now.b-w2]=true; q.push(tmp); } } printf("impossible\n"); } int main() { while(scanf("%d%d%d",&A,&B,&C)!=EOF) { memset(vis,false,sizeof(vis)); vis[0][0]=true; Node que; que.a=que.b=0; que.sum=0; bfs(que); } return 0; }
手写queue(时间会快很多):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int Max = 101; struct node { int ope; int a; int b; node* pre; }que[Max*Max]; //队列结点,ope记录第几种操作,a,b记录此结点两个pot的水数。 bool vis[Max][Max]; char str[6][10] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"}; void print(node now) { if(now.pre!=NULL) { print(*now.pre); cout<<str[now.ope]<<endl; } } void bfs(int a,int b,int c) //手写queue { int steps=0; int head=0,tail=1; //队列的开始和结尾 que[0].a=que[0].b=0; que[0].pre=NULL; while(tail-head>0) { int count=tail-head; while(count--) { node now=que[head]; if(now.a==c||now.b==c) { cout<<steps<<endl; print(now); return; } //FILL(1); if(!vis[a][now.b]) { que[tail].ope = 0; que[tail].a = a; que[tail].b = now.b; que[tail].pre = &que[head]; vis[a][now.b] = true; tail ++; } //FILL(2) if(!vis[now.a][b]) { que[tail].ope = 1; que[tail].a = now.a; que[tail].b = b; que[tail].pre = &que[head]; vis[now.a][b] = true; tail ++; } //DROP(1); if(!vis[0][now.b]) { que[tail].ope = 2; que[tail].a = 0; que[tail].b = now.b; que[tail].pre = &que[head]; vis[0][now.b] = true; tail ++; } //DROP(2) if(!vis[now.a][0]) { que[tail].ope = 3; que[tail].a = now.a; que[tail].b = 0; que[tail].pre = &que[head]; vis[now.a][0] = true; tail ++; } //POUR(1,2) int wat1 = min(now.a, b - now.b); if(!vis[now.a - wat1][now.b + wat1]) { que[tail].ope = 4; que[tail].a = now.a - wat1; que[tail].b = now.b + wat1; que[tail].pre = &que[head]; vis[now.a - wat1][now.b + wat1] = true; tail ++; } //POUR(2,1) int wat2 = min(a - now.a, now.b); if(!vis[now.a + wat2][now.b - wat2]) { que[tail].ope = 5; que[tail].a = now.a + wat2; que[tail].b = now.b - wat2; que[tail].pre = &que[head]; vis[now.a + wat2][now.b - wat2] = true; tail ++; } head++; } steps++; } cout<<"impossible"<<endl; } int main() { int a,b,c; cin>>a>>b>>c; memset(vis,false,sizeof(vis)); vis[0][0]=true; bfs(a,b,c); return 0; }
本文版权归作者本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.