題目連接:https://vjudge.net/problem/HDU-1495
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 Inputios
7 4 3 4 1 3 0 0 0
Sample Outputc++
NO 3
解題思路一:數論解法,證實可見:https://blog.csdn.net/xiaolonggezte/article/details/70795894
Cpp Codespa
#include<bits/stdc++.h> using namespace std; int main() { int a,b,c; while( ~ scanf("%d%d%d",&a,&b,&c)) { if(a == 0 && b == 0 && c == 0) break; int g = __gcd(b,c); if((b + c) / g % 2) { cout << "NO" << endl; continue; } cout << (b + c) / g - 1 << endl; } return 0; }
解題思路二:開始的時候,全部可樂在s中,2個杯子n和m都空着。過程當中,能夠將任何1個容器中的可樂倒到另外某個容器中,或將目標容器倒滿,或將源容器倒空。由於容器沒有刻度,只能這樣。這個過程當中,若是出現某個容器空,另外2個容器可樂相同則成功。若是開始的時候,可樂的容量是奇數,則不可能平分可樂。容器間可樂倒來倒去,每次有6種倒法,對這6種倒法進行試探便可。求的是最少倒的次數,因此能夠用BFS實現。.net
Cpp Codecode
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<queue> using namespace std; const int maxn = 110; struct Status{ int s, a, b, t; } st; bool vis[maxn][maxn]; int s, a, b; int bfs(){ queue<Status> q; memset(vis, 0, sizeof(vis)); st.a = 0; st.b = 0; st.s = s; st.t = 0; vis[a][b] = 1; q.push(st); while (!q.empty()) { Status v, u = q.front(); if(u.a==s/2&&u.s==s/2){ return u.t; } if(u.s&&u.a!=a){ int c = a - u.a; if(u.s>=c){ v.a = a; v.s = u.s - c; } else{ v.a = u.a + u.s; v.s = 0; } v.b = u.b; v.t = u.t + 1; if(!vis[v.a][v.b]){ vis[v.a][v.b] = 1; q.push(v); } } if(u.s&&u.b!=b){ int c = b - u.b; if(u.s>=c){ v.b = b; v.s = u.s - c; } else{ v.b = u.b + u.s; v.s = 0; } v.a = u.a; v.t = u.t + 1; if(!vis[v.a][v.b]){ vis[v.a][v.b] = 1; q.push(v); } } if(u.a&&u.b!=b){ int c = b - u.b; if(u.a>=c){ v.b = b; v.a = u.a - c; } else{ v.b = u.b + u.a; v.a= 0; } v.s = u.s; v.t = u.t + 1; if(!vis[v.a][v.b]){ vis[v.a][v.b] = 1; q.push(v); } } if(u.a&&u.s!=s){ int c = s - u.s; if(u.a>=c){ v.s = s; v.a = u.a - c; } else{ v.s = u.s + u.a; v.a= 0; } v.b = u.b; v.t = u.t + 1; if(!vis[v.a][v.b]){ vis[v.a][v.b] = 1; q.push(v); } } if(u.b&&u.a!=a){ int c = a - u.a; if(u.b>=c){ v.a = a; v.b = u.b - c; } else{ v.a = u.a + u.b; v.b= 0; } v.s = u.s; v.t = u.t + 1; if(!vis[v.a][v.b]){ vis[v.a][v.b] = 1; q.push(v); } } if(u.b&&u.s!=s){ int c = s - u.s; if(u.b>=c){ v.s = s; v.b = u.b - c; } else{ v.s = u.s + u.b; v.b= 0; } v.a = u.a; v.t = u.t + 1; if(!vis[v.a][v.b]){ vis[v.a][v.b] = 1; q.push(v); } } q.pop(); } return 0; } int main(){ while ((cin>>s>>a>>b)&&(a||b||s)) { if(s%2==1){ cout << "NO" << endl; } else{ if(a<b){ swap(a, b); } int ans = bfs(); if(ans){ cout << ans << endl; } else{ cout << "NO" << endl; } } } return 0; }