1. 程式人生 > >hdu 1495

hdu 1495

bsp pre c++ rip include desc 們的 out names

1、鏈接

http://acm.hdu.edu.cn/showproblem.php?pid=1495

2、題目

Description
大家一定覺的運動以後喝可樂是一件很愜意的事情,但是seeyou卻不這麽認為。因為每次當seeyou買了可樂以後,阿牛就要求和seeyou一起分享這一瓶可樂,而且一定要喝的和seeyou一樣多。但seeyou的手中只有兩個杯子,它們的容量分別是N 毫升和M 毫升 可樂的體積為S (S<101)毫升 (正好裝滿一瓶) ,它們三個之間可以相互倒可樂 (都是沒有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聰明的ACMER你們說他們能平分嗎?如果能請輸出倒可樂的最少的次數,如果不能輸出"NO"。

Input
三個整數 : S 可樂的體積 , N 和 M是兩個杯子的容量,以"0 0 0"結束。

Output
如果能平分的話請輸出最少要倒的次數,否則輸出"NO"。

Sample Input
7 4 3
4 1 3
0 0 0

Sample Output
NO
3

3、解題分析:

求平分可樂的最少次數,彼此互相倒,所以存在6種狀態:

s->n  ②s->m

③n->s  ④m->s

⑤n->m  ⑥m->n

屬於bfs搜索類型的題(有狀態,求最少)

想明白一個寫出來,其余狀態都一個思路

4、代碼

#include<bits/stdc++.h>
using
namespace std; struct Volum { int Vs; int Vn; int Vm; int step; }; int vis[105][105]; int s,n,m; queue<Volum>q; int bfs(int a,int b, int c) { while(!q.empty()) { q.pop(); } Volum V1; V1.Vs = s; V1.Vn = 0; V1.Vm = 0; q.push(V1); vis[n][m]
= 1; while(!q.empty()) { Volum tmp = q.front(); Volum tmp1; if(tmp.Vn == s/2 && tmp.Vs == s/2) ///tmp 這個結構體中的 Vs 和 Vn 均為 s的一半,符合條件直接返回 { return tmp.step; } ///s -> n 由 s 向 n 倒 if(tmp.Vs && tmp.Vn != n) { int c = n - tmp.Vn; if(tmp.Vs >= c) { tmp1.Vs = tmp.Vs - c; tmp1.Vn = n; } else { tmp1.Vs = 0; tmp1.Vn = tmp.Vn + tmp.Vs; } tmp1.Vm = tmp.Vm; tmp1.step = tmp.step + 1; if(!vis[tmp1.Vn][tmp1.Vm]) { q.push(tmp1); vis[tmp1.Vn][tmp1.Vm] = 1; } } ///s -> m if(tmp.Vs && tmp.Vm != m) { int c = m - tmp.Vm; if(tmp.Vs >= c) { tmp1.Vs = tmp.Vs - c; tmp1.Vm = m; } else { tmp1.Vs = 0; tmp1.Vm = tmp.Vm + tmp.Vs; } tmp1.Vn = tmp.Vn; tmp1.step = tmp.step + 1; if(!vis[tmp1.Vn][tmp1.Vm]) { q.push(tmp1); vis[tmp1.Vn][tmp1.Vm] = 1; } } /// n -> s if(tmp.Vn && tmp.Vs != s) { int c = s - tmp.Vs; if(tmp.Vn >= c) { tmp1.Vn = tmp.Vn - c; tmp1.Vs = s; } else { tmp1.Vn = 0; tmp1.Vs = tmp.Vs + tmp.Vn; } tmp1.Vm = tmp.Vm; tmp1.step = tmp.step + 1; if(!vis[tmp1.Vn][tmp1.Vm]) { q.push(tmp1); vis[tmp1.Vn][tmp1.Vm] = 1; } } /// m -> s if(tmp.Vm && tmp.Vs != s) { int c = s - tmp.Vs; if(tmp.Vm >= c) { tmp1.Vm = tmp.Vm - c; tmp1.Vs = s; } else { tmp1.Vm = 0; tmp1.Vs = tmp.Vs + tmp.Vm; } tmp1.Vn = tmp.Vn; tmp1.step = tmp.step + 1; if(!vis[tmp1.Vn][tmp1.Vm]) { q.push(tmp1); vis[tmp1.Vn][tmp1.Vm] = 1; } } /// n -> m if(tmp.Vn && tmp.Vm != m) { int c = m - tmp.Vm; if(tmp.Vn >= c) { tmp1.Vn = tmp.Vn - c; tmp1.Vm = m; } else { tmp1.Vn = 0; tmp1.Vm = tmp.Vm + tmp.Vn; } tmp1.Vs = tmp.Vs; tmp1.step = tmp.step + 1; if(!vis[tmp1.Vn][tmp1.Vm]) { q.push(tmp1); vis[tmp1.Vn][tmp1.Vm] = 1; } } /// m -> n if(tmp.Vm && tmp.Vn != n) { int c = n - tmp.Vn; if(tmp.Vm >= c) { tmp1.Vm = tmp.Vm - c; tmp1.Vn = n; } else { tmp1.Vm = 0; tmp1.Vn = tmp.Vn + tmp.Vm; } tmp1.Vs = tmp.Vs; tmp1.step = tmp.step + 1; if(!vis[tmp1.Vn][tmp1.Vm]) { q.push(tmp1); vis[tmp1.Vn][tmp1.Vm] = 1; } } q.pop(); } return 0; } int main() { while(~scanf("%d%d%d",&s,&n,&m)) { memset(vis,0,sizeof(vis)); if(s == 0 && n == 0 && m == 0) break; if(s % 2 != 0){ printf("NO\n"); continue; } if(n<m) swap(n,m); int ans = bfs(s,n,m); if(ans) printf("%d\n",ans); else printf("NO\n"); } return 0; }

hdu 1495