poj 3414 bfs 兩個壺倒水,記錄路徑
阿新 • • 發佈:2019-02-15
題意:給你兩個壺,容量分別為a,b,初始都是0,再給你一個目標水量c,問經過幾次操作可以使得其中一個壺的水量為目標水量c,並且把操作步驟輸出。
6個操作:
1、FILL(1)//FILL(i),把 i 壺裝滿
2、FILL(2)
3、DROP(1)//DROP(i),把 i 壺倒光
4、DROP(2)
5、POUR(1,2)//POUR(i,j)從 i 壺裡倒水到 j 壺,直至 i 壺空了,或者 j 壺滿了
6、POUR(2,1)
bfs最短路,關鍵點:
佇列元素:兩個壺的水量、在佇列裡的位置、上一個操作在佇列裡的位置、達到這個水量的操作(這三步是為了記錄路徑)
程式碼:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int ms = 3e6; struct node{ int a,b; int index; int way; int last; }; node queue[ms]; int front,rear,visit[105][105] = {0},path[ms]; void Init(){ front = rear = 0; } bool IsEmpty(){ if(front == rear) return true; return false; } void Push(node x){ if(visit[x.a][x.b]) return; visit[x.a][x.b] = 1; x.index = rear; queue[rear++] = x; return; } void Pop(){ front++; return; } void Print(int w){ if(w == 1){ printf("FILL(1)\n"); return; } if(w == 2){ printf("FILL(2)\n"); return; } if(w == 3){ printf("DROP(1)\n"); return; } if(w == 4){ printf("DROP(2)\n"); return; } if(w == 5){ printf("POUR(1,2)\n"); return; } if(w == 6){ printf("POUR(2,1)\n"); return; } return; } int main(){ int m1,m2,c,k; while(scanf("%d %d %d",&m1,&m2,&c) != EOF){ k = -1; Init(); node start; start.a = start.b = 0; start.index = 0; start.last = -1; start.way = -1; queue[0] = start; rear = 1; visit[0][0] = 1; while(!IsEmpty()){ node top = queue[front]; Pop(); if(top.a ==c || top.b ==c){ int pos = top.index; while(queue[pos].way != -1){ path[++k] = queue[pos].way; pos = queue[pos].last; } printf("%d\n",k+1); while(k >= 0){ Print(path[k]); k--; } k = 0; break; } node newn; newn.last = top.index; //FILL(1) = 1; newn.a = m1; newn.b = top.b; newn.way = 1; Push(newn); //FILL(2) = 2; newn.a = top.a; newn.b = m2; newn.way = 2; Push(newn); //DROP(1) = 3; newn.a = 0; newn.b = top.b; newn.way = 3; Push(newn); //DROP(2) = 4; newn.a = top.a; newn.b = 0; newn.way = 4; Push(newn); //POUR(1,2) = 5; int tmp = m2 - top.b; if(tmp <= top.a){ newn.a = top.a - tmp; newn.b = m2; } else{ newn.a = 0; newn.b = top.b + top.a; } newn.way = 5; Push(newn); //POUR(2,1) = 6; tmp = m1 - top.a; if(tmp <= top.b){ newn.a = m1; newn.b = top.b - tmp; } else{ newn.a = top.a + top.b; newn.b = 0; } newn.way = 6; Push(newn); } if(k == -1) printf("impossible\n"); } }