HDU-1495___非常可樂——數論 或 BFS
阿新 • • 發佈:2018-12-16
題目大意:
一杯可樂,兩個杯子,體積分別為, , 。一開始可樂是滿的,問怎麼互相倒,可以對半分 ???
解題思路:
六入口BFS,很簡單,但是看了另一個人的數論解題,感覺很牛X 這裡貼出數論解題的部落格:點我啊點我啊
程式碼思路:
BFS 或 數論
核心:數論的運用
數論:
#include<bits/stdc++.h> using namespace std; int gcd(int a, int b){ return b ? gcd(b, a%b) : a; } int main() { int a, b, c; while(scanf("%d%d%d", &a,&b,&c), a+b+c) { a /= gcd(b,c); if(a&1) printf("NO\n"); else printf("%d\n", a-1); } }
BFS:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int a, b, c, ans; bool vis[105][105][105]; struct pot { int s, u, v; int step; }; void BFS() { queue <pot> Q; pot q, n; q.s = a, q.u = 0, q.v = 0; q.step = 0; Q.push(q); vis[a][0][0] = true; while(!Q.empty()) { q = Q.front(); Q.pop(); for(int i=1; i<=6; i++) { if(i==1 && q.s && q.u!=b) { // a->b if(b-q.u>q.s) { n.s = 0; n.u = q.s + q.u; n.v = q.v; } else { n.s = q.s - (b - q.u); n.u = b; n.v = q.v; } } if(i==2 && q.s && q.v!=c) { // a->c if(c-q.v>q.s) { n.s = 0; n.u = q.u; n.v = q.s + q.v; } else { n.s = q.s - (c - q.v); n.u = q.u; n.v = c; } } if(i==3 && q.u && q.s!=a) { // b->a if(a-q.s>q.u) { n.s = q.s + q.u; n.u = 0; n.v = q.v; } else { n.s = a; n.u = q.u - (a - q.s); n.v = q.v; } } if(i==4 && q.u && q.v!=c) { // b->c if(c-q.v>q.u) { n.s = q.s; n.u = 0; n.v = q.u + q.v; } else { n.s = q.s; n.u = q.u - (c - q.v); n.v = c; } } if(i==5 && q.v && q.s!=a) { // c->a if(a-q.s>q.v) { n.s = q.s + q.v; n.u = q.u; n.v = 0; } else { n.s = a; n.u = q.u; n.v = q.v - (a - q.s); } } if(i==6 && q.v && q.u!=b) { // c->b if(b-q.u>q.v) { n.s = q.s; n.u = q.u + q.v; n.v = 0; } else { n.s = q.s; n.u = b; n.v = q.v - (b - q.u); } } if(vis[n.s][n.u][n.v]) continue; vis[n.s][n.u][n.v] = true; n.step = q.step + 1; if(n.s==a/2&&n.u==a/2 || n.s==a/2&&n.v==a/2 || n.u==a/2&&n.v==a/2) { ans = n.step; return; } Q.push(n); } } } int main() { while(scanf("%d%d%d", &a, &b, &c), a) { memset(vis, 0, sizeof(vis)); ans = 0; if(a%2){ printf("NO\n"); continue; } BFS(); if(!ans) printf("NO\n"); else printf("%d\n", ans); } }