非常可樂
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"。
Author
seeyou
解題思路:
寬度優先搜素
or 數論
感覺和 POJ 上的這題差不多,都是關於操作步驟的,用 bfs
就可以了–>- POJ 3414 Pots(bfs)-
不過後來看到 discuss 裏面居然有人直接用 gcd
就過了,然後又看到一種貌似更復雜的?提到數論
和裴蜀定理
,這,,,見多識廣真好~o( ̄︶ ̄)o
代碼:
① bfs:
Exe.Time : 15MS | Exe.Memory : 1796K
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
#define INF 0x3f3f3f
#define zero 1e-7
typedef long long ll;
const int N=110;
int vis[N][N];//i|j分別表示兩個杯子中的水量,vis記錄到達這種狀態最少需要的步驟
int s, n, m;
struct node {
int v1, v2, v3;
};
queue<node> q;
int bfs(int vs, int vn, int vm) {
while(!q.empty()) q.pop();
node st={vs, vn, vm};
q.push(st);
vis[vn][vm]=0;
while(!q.empty()) {
node top=q.front();
//printf("top.v1=%d, v2=%d, v3=%d\n", top.v1, top.v2, top.v3);
q.pop();
if((top.v1==top.v2 && !top.v3) || (top.v1==top.v3 && !top.v2) || (top.v2==top.v3 && !top.v1))
return vis[top.v2][top.v3];
int a=top.v1, b=top.v2, c=top.v3;
for(int i=0; i<6; i++) {
switch(i) {
case 0: //s-->n(之前不小心把數字打成字符了,所以實際上並沒有進行任何操作
if(top.v1+top.v2>=n)
b=n, a=top.v1+top.v2-n;
else
a=0, b=top.v1+top.v2;
c=top.v3;
break;
case 1://s-->m
if(top.v1+top.v3>=m)
c=m, a=top.v1+top.v3-m;
else
a=0, c=top.v1+top.v3;
b=top.v2;
break;
case 2://n-->s
a=top.v1+top.v2;
b=0;
c=top.v3;
break;
case 3://n-->m
if(top.v2+top.v3>=m)
c=m, b=top.v2+top.v3-m;
else
b=0, c=top.v2+top.v3;
a=top.v1;
break;
case 4://m-->s
a=top.v1+top.v3;
c=0;
b=top.v2;
break;
case 5://m-->n
if(top.v2+top.v3>=n)
b=n, c=top.v2+top.v3-n;
else
c=0, b=top.v2+top.v3;
a=top.v1;
break;
}
//printf("vis[%d][%d]=%d\n", b, c, vis[b][c]);
if(vis[b][c]==-1) {
vis[b][c]=vis[top.v2][top.v3]+1;
node temp={a, b, c};
q.push(temp);
}
}
}
return -1;
}
int main() {
while(scanf("%d %d %d", &s, &n, &m)!=EOF, s || n || m) {
if(s%2) printf("NO\n");
else {
memset(vis, -1, sizeof(vis));
int ans=bfs(s, 0, 0);
if(ans!=-1) printf("%d\n", ans);
else printf("NO\n");
}
}
return 0;
}
//ps: 過了就非常可樂(#^.^#)
② gcd:
Exe.Time : 46MS | Exe.Memory : 1804K
#include <iostream>
#include <algorithm>
using namespace std;
int gcd(int a, int b) {
return a%b ? gcd(b, a%b) : b;
}
void print(int a) {
if(a & 1) cout << "NO\n";
else cout << a-1 << endl;
}
int main()
{
int a, b, c;
while((cin>>a>>b>>c) && (a||b||c)) {
a /= gcd(b, c);
print(a);
}
}
③ 數論:
Exe.Time : 31MS | Exe.Memory : 1740K
鏈接:- 衝啊小籠包 -
PS: 事實證明,還是 bfs 跑得快一點,就是代碼有點長~