poj3414
来源:互联网 发布:阿里小号 知乎 编辑:程序博客网 时间:2024/06/10 06:54
题目名称: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;}
0 0
- poj3414
- poj3414
- poj3414
- poj3414
- poj3414
- poj3414
- POJ3414
- POJ3414 Pots
- poj3414 Pots
- POJ3414 BFS
- poj3414 Pots
- poj3414 - Pots
- POJ3414--Pots
- POJ3414 Pots
- poj3414 Pots
- poj3414 Pots
- POj3414 Pots
- poj3414 Pots
- 对象析构谈—— delete this 的使用及注意事项
- HDU 3966 Aragorn's Story(树链剖分+线段树区间更新+手动扩大内存)
- 工具类
- 【UIKit】-12-UIApplication - appDelegate 中
- an error has occurred.See error log for more details
- poj3414
- Android OTG (USB Hos) 编程
- 堆与堆排序
- powershell远程管理服务器磁盘空间
- DataTable行列转换
- 对互联网海量数据实时计算的理解
- 黑马程序员——JAVASE-反射
- Lucene四(Luke工具的使用)
- SPOJ BALNUM (数位DP+状压)