poj 3414 倒水問題 bfs

2021-07-02 03:41:55 字數 1710 閱讀 5473

思路:就是bfs,有六種操作,fill 1或2,drop 1或2 ,將1倒到2,將2倒到1。要注意的是要使用標記陣列vis[i][j] 表示左邊的杯子為i公升,右邊的杯子為j公升,如果已被標記說明之前已經出現這種情況,就不要入隊。從(0,0)開始bfs。

因為題目中需要輸出如何倒,那麼就需要儲存路徑。。以前似乎自己還沒有寫過,只是知道這種思想,用乙個陣列記錄下當前位置的前乙個位置的座標。最後通過終點找回去,找出整條路徑,將路上的每個點都儲存到答案陣列中,(這裡我是逆著儲存的,也就是終點儲存在最後面),最後輸出的時候順著遍歷一遍答案陣列,比較前後兩個的情況,輸出操作。

**:#include #include #include #include #include #include using namespace std;

#define m 109

#define inf 0x3f3f3f3f

int vis[m][m];

int n,m,k;

int ans;

struct state

cur,next1;

struct

s[m][m]; //記錄路徑 儲存上乙個點座標

struct

ss[100009]; //儲存答案的陣列

void bfs(state temp)

return ;

}next1.step = cur.step+1;

if(cur.y < m) //倒滿y

}if(cur.x < n) //倒滿x

}if(cur.x > 0)

if(cur.y < m) //x倒到y

else

if(!vis[next1.x][next1.y])}}

if(cur.y > 0)

if(cur.x < n)//y倒到x

else

if(!vis[next1.x][next1.y])}}

}}int main()

{    while(scanf("%d %d %d",&n,&m,&k)==3)

{memset(vis,0,sizeof(vis));

memset(ss,0,sizeof(ss));

memset(s,0,sizeof(s));

ans = inf;

cur.x = 0;

cur.y = 0;

bfs(cur);

if(ans==inf)

printf("impossible\n");

else

{//ss[0].a = 0;

//ss[0].b = 0;

for(int i = 0;i < ans;i++)

{int x1 = ss[i].a;

int y1 = ss[i].b;

int x2 = ss[i+1].a;

int y2 = ss[i+1].b;

if(x1==0 && x2==n && y1==y2) printf("fill(1)\n");  //要寫清楚情況 fill的時候必須y是不變的。。

if(y1==0 && y2==m && x1==x2) printf("fill(2)\n");

if(x1>0 && x2==0 && y1==y2) printf("drop(1)\n");

if(x2>0 && y2==0 && x1==x2) printf("drop(2)\n");

if(y2>y1 && x2x1 && y2

搜尋 poj3414倒水問題

題意 給出a,b兩個水杯的容量,和乙個要達到的水量c。總共3種操作,兩個杯子那就是六種。要求通過這六種操作來時兩個杯子其中有乙個水量為c的最少運算元。解題思路 這道題用到的是廣搜bfs,水量 i,j 代表乙個點,通過這六種操作可以變成另乙個點,那麼這兩個點之間就是有路的,每個點有沒有訪問過用鄰接矩陣...

POJ3414解題報告

include includeconst int maxn 110 int vis maxn maxn 標記狀態是否入隊過 int a,b,c 容器大小 int step 最終的步數 int flag 紀錄是否能夠成功 狀態紀錄 struct statusq maxn maxn int id max...

POJ 3414(BFS 輸出路徑 倒水問題)

題意 給你兩個容器,分別能裝下a公升水和b公升水,並且可以進行以下操作 fill i 將第i個容器從水龍頭裡裝滿 1 i 2 drop i 將第i個容器抽乾 pour i,j 將第i個容器裡的水倒入第j個容器 這次操作結束後產生兩種結果,一是第j個容器倒滿並且第i個容器依舊有剩餘,二是第i個容器裡的...