1. 程式人生 > >POJ 3414 -- Pots

POJ 3414 -- Pots

沒有 chan pan mov 父節點 以及 表示 不可 http

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 }

技術分享圖片

POJ 3414 -- Pots