非常可樂
Problem 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
題解:這一題難點兒的都在不好想,尤其是搜索時候的模擬過程(即相互倒水的過程),想會這點兒基本上就能做了,但是有一點,標記數組vis別開大,不然就 TE , 我開的是vis[109][109][109] TE 了,換成vis[105][105][105]過了,雖然卡着時間過去的
先來看一下搜索的代碼:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int s[3] , vis[105][105][105];
struct cup{
int c[3] , step;
}now;
int bfs(){
queue<cup> q ;
now.c[0] = s[0] ,now.c[1] = 0 , now.c[2] = 0 , now.step = 0;
vis[now.c[0]][now.c[1]][now.c[2]] = 1;
q.push(now);
while(!q.empty()){
now = q.front();
if((now.c[0] == now.c[1] && now.c[2] == 0) || (now.c[0] == now.c[2] && now.c[1] == 0) || (now.c[1] == now.c[2] && now.c[0] == 0))
//判斷終止條件,即有一個杯子是空,另外兩個杯子一樣多
{
return now.step;
}
q.pop();
for(int i = 0 ; i < 3 ; i ++){
//模擬倒水的 6 種情況 a 倒 b,c || b倒 a , c || c 倒 a , b
for(int j = 0 ; j < 3 ; j ++){
if(i != j){ // 非自己倒給自己的過程,即其他的倒水過程
int k = s[j] - now.c[j];
if(k > now.c[i]){
k = now.c[i];
}
cup next = now;
//第 i 杯往第 j 杯裏倒水過程
next.c[i] = now.c[i] - k;
next.c[j] = now.c[j] + k;
next.step = now.step + 1;
if(vis[next.c[0]][next.c[1]][next.c[2]] == 0){
vis[next.c[0]][next.c[1]][next.c[2]] = 1;
q.push(next);
}
}
}
}
}
return -1;
}
int main(){
while(cin >> s[0] >> s[1] >> s[2] && s[0] + s[1] + s[2]){
memset(vis,0,sizeof(vis));
if(s[0] != s[1] + s[2]){
printf("NO\n");
break;
}
else{
int ans = bfs();
if(ans == -1)
printf("NO\n");
else
printf("%d\n",ans);
}
}
return 0 ;
}
還有一種數論的做法,可以參考一下https://blog.csdn.net/V5ZSQ/article/details/52097459這位大佬的講解很詳細,望對你們有幫助,
附上數論代碼;
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
int a , b , c;
while(cin >> a >> b >> c && (a + b + c)){
a /= __gcd(b,c);
if(a & 1)
cout<<"NO\n";
else
cout<< a-1 <<endl;
}
return 0 ;
}