1. 程式人生 > >非常可樂

非常可樂

容易 一個 代碼 輸出 queue sizeof ems include 小數據

題意就是給你仨瓶子,一個是可樂瓶,兩個空瓶,三個都能用,你要倒來倒去來用兩個瓶子平分第一個瓶裏的可樂,但是倒的時候只能把瓶子倒滿。輸出平分需要的最少步驟,若不能輸出NO;

廣搜把每一步的結果都記錄下來,自己可以找點小數據在紙上試試就明白了,代碼有點長思路很清晰。註意一下標記就可以了,沒有太大坑點,主要在理解。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <string.h>
#include <stack>
#define
LL long long #define mem(a) memset(a,0,sizeof(a)) int M,N,S,vis[105][105][105]; struct node { int s,n,m,step; }; std::queue<node> q; int bfs() { node a,t; int i,k; mem(vis); while(q.size()) q.pop(); a.s=S; a.m=0; a.n=0; a.step=0; q.push(a); vis[a.s][
0][0]=1; while(q.size()) { a=q.front(); q.pop(); if(a.s==S/2&&a.m==S/2||a.s==S/2&&a.n==S/2||a.m==S/2&&a.n==S/2) return a.step; for(i=0;i<6;i++)//倒可樂的循環步驟,光看是不容易理解的,自己找數據親自試試,想想 { if(i==0)///S-->M { k
=a.s<(M-a.m)?a.s:(M-a.m); t.s=a.s-(M-a.m); t.m=a.m+k; t.n=a.n; } else if(i==1)///M-->S { k=a.m<(S-a.s)?a.m:(S-a.s); t.s=a.s+k; t.m=a.m-k; t.n=a.n; } else if(i==2)///S-->N { k=a.s<(N-a.n)?a.s:(N-a.n); t.s=a.s-k; t.n=a.n+k; t.m=a.m; } else if(i==3)///N-->S { k=a.n<(S-a.s)?a.n:(S-a.s); t.s=a.s+k; t.n=a.n-k; t.m=a.m; } else if(i==4)///M-->N { k=a.m<(N-a.n)?a.m:(N-a.n); t.s=a.s; t.m=a.m-k; t.n=a.n+k; } else///N-->M { k=a.n<(M-a.m)?a.n:(M-a.m); t.s=a.s; t.m=a.m+k; t.n=a.n-k; } if(!vis[t.s][t.m][t.n]) { t.step=a.step+1; vis[t.s][t.m][t.n]=1; q.push(t); } } } return -1; } int main() { while(scanf("%d%d%d",&S,&N,&M),M+S+N) { if(S%2>0) printf("NO\n"); else { int k=bfs(); if(k!=-1) printf("%d\n",k); else printf("NO\n"); } } return 0; }

非常可樂