POJ 3414 -- Pots
POJ 3414 -- Pots
题意:
给出了两个瓶子的容量A,B, 以及一个目标水量C,
对A、B可以有如下操作:
FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
DROP(i) empty the pot i to the drain;
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).
问经过哪几个操作后能使得任意一个瓶子的残余水量为C。
若不可能得到则输出impossible
解题思路:
6入口bfs,啊...很典型的bfs...
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int maxn = 101+5;//杯子中水的水量的取值范围为0~100 5 ///定义6个动作,使用数组下标0~5存储 6 const char* action[] = {"FILL(1)","FILL(2)","POUR(1,2)", 7 "POUR(2,1)","DROP(1)","DROP(2)"}; 8 int a,b,c; 9 struct node{ 10 int anum,bnum;//记录节点,A中的水量,B中的水量 11 int index;//记录action数组的下标,父节点是通过什么动作到达当前节点 12 int deep;//记录深度 13 int par;//记录父节点 14 }; 15 ///为防止访问相同的结点,使用二维数组visit[i][j], 16 ///表示A中水量为i,B中水量为j时的状态是否被访问过。 17 bool visit[maxn][maxn]; 18 19 ///因为重复的结点不会访问,所以最多的结点数为maxn*maxn 20 node queue[maxn*maxn]; 21 int ans[maxn*maxn]; 22 23 void change(int na,int nb,int &ta,int &tb,int i) 24 {///"FILL(1)","FILL(2)","POUR(1,2)","POUR(2,1)","DROP(1)","DROP(2)" 25 if(i == 0)//"FILL(1)" 26 { 27 ta = a;tb = nb; 28 } 29 else if(i==1) 30 { 31 ta = na;tb = b; 32 } 33 else if(i==2) 34 { 35 if(na>=(b-nb))///把b倒满 36 { 37 ta = na - (b-nb);tb = b; 38 } 39 else{///把a倒空 40 ta = 0;tb = na+nb; 41 } 42 } 43 else if(i==3) 44 { 45 if(nb>=(a-na))///把a倒满 46 { 47 tb = nb - (a-na);ta = a; 48 } 49 else{///把b倒空 50 tb = 0;ta = nb+na; 51 } 52 } 53 else if(i==4) 54 { 55 ta = 0;tb = nb; 56 } 57 else{ 58 tb = 0;ta = na; 59 } 60 } 61 62 ///六入口的bfs 63 bool bfs() 64 { 65 ///定义状态 66 queue[0].anum = 0; 67 queue[0].bnum = 0; 68 queue[0].deep = 0; 69 queue[0].index = -1; 70 queue[0].par = -1; 71 visit[0][0] = true; 72 int head = 0,rear = 1; 73 while(head<rear) 74 { 75 node u = queue[head]; 76 if((u.anum==c)||(u.bnum==c)) 77 {///得到目标状态 78 int dept = u.deep; 79 cout<<dept<<endl; 80 for(int i=u.deep;i>0;i--) 81 { 82 if(u.par == -1) break; 83 ans[i] = u.index; 84 u = queue[u.par]; 85 } 86 for(int i=1;i<=dept;i++) 87 cout<<action[ans[i]]<<endl; 88 return true; 89 } 90 for(int i=0;i<6;i++)///遍历6个入口 91 { 92 int ta,tb; 93 change(u.anum,u.bnum,ta,tb,i); 94 if(!visit[ta][tb]) 95 {///当前状态没有被访问过 96 queue[rear].anum = ta; 97 queue[rear].bnum = tb; 98 queue[rear].deep = u.deep+1; 99 queue[rear].index = i; 100 queue[rear].par = head; 101 visit[ta][tb] = true; 102 rear++; 103 } 104 } 105 head++; 106 } 107 return false; 108 } 109 int main() 110 { 111 while(cin>>a>>b>>c) 112 { 113 memset(visit,false,sizeof(visit)); 114 if(!bfs()) 115 cout<<"impossible"<<endl; 116 } 117 return 0; 118 }