HDU - 1495 非常可樂(BFS列舉 or 數論)
阿新 • • 發佈:2018-11-10
題目大意
三個cup,容量分別為s,n,m(s=n+m),cup沒有刻度(這個真的坑,就是要麼倒完要麼倒滿)。初始狀況,s滿,n、m空,求能否通過相互之間倒可樂,把可樂平分。能的話,輸出最小次數。
分析
每次倒都有6種情況s-n,s-m.....。可以BFS分別列舉每種倒法。很明顯s為奇數,NO。
vis也能起到終止作用吧,每種情況都走過被標記了。佇列為空,則返回-1,表示不能平分。
要注意 只有當下一狀態條件滿足並且沒有走過時,才讓其level+1;
聽說數論也能做,但我 不會!
AC Code
#include<bits/stdc++.h> typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1e2+5; using namespace std; int s,n,m; bool vis[maxn][maxn][maxn]; struct node { int s,m,n,level; }; bool judge(node &tar) { int ans=s/2; if(tar.s==ans&&tar.n==ans||tar.s==ans&&tar.m==ans||tar.n==ans&&tar.m==ans) return 1; return 0; } int bfs() { if(s%2) return -1; memset(vis,0,sizeof(vis)); queue<node> q; node cur,next; cur.s=s; cur.n=0; cur.m=0; cur.level=0; vis[s][0][0]=1; q.push(cur); while(!q.empty()) { cur=q.front(); q.pop(); //6 zhong if(cur.s&&n-cur.n>0) { //s->n if(cur.s>=(n-cur.n)) { //s能夠倒滿n next.s=cur.s-(n-cur.n); next.n=n; } else { next.s=0; next.n=cur.n+cur.s; } next.m=cur.m; if(!vis[next.s][next.n][next.m]) { next.level=cur.level+1;//要放入if裡 vis[next.s][next.n][next.m]=1; q.push(next); } if(judge(next)) return next.level; } //s->m if(cur.s&&n-cur.m>0) { //s->n if(cur.s>=(m-cur.m)) { next.s=cur.s-(m-cur.m); next.m=m; } else { next.s=0; next.m=cur.m+cur.s; } next.n=cur.n; if(!vis[next.s][next.n][next.m]) { next.level=cur.level+1; vis[next.s][next.n][next.m]=1; q.push(next); } if(judge(next)) return next.level; } //n->s if(cur.n&&s-cur.s>0) { //s->n if(cur.n>=(s-cur.s)) { next.n=cur.n-(s-cur.s); next.s=s; } else { next.n=0; next.s=cur.s+cur.n; } next.m=cur.m; if(!vis[next.s][next.n][next.m]) { next.level=cur.level+1; vis[next.s][next.n][next.m]=1; q.push(next); } if(judge(next)) return next.level; } //n->m if(cur.n&&m-cur.m>0) { //s->n if(cur.n>=(m-cur.m)) { next.n=cur.n-(m-cur.m); next.m=m; } else { next.n=0; next.m=cur.m+cur.n; } next.s=cur.s; if(!vis[next.s][next.n][next.m]) { next.level=cur.level+1; vis[next.s][next.n][next.m]=1; q.push(next); } if(judge(next)) return next.level; } //m->s if(cur.m&&s-cur.s>0) { //s->n if(cur.m>=(s-cur.s)) { next.m=cur.m-(s-cur.s); next.s=s; } else { next.m=0; next.s=cur.s+cur.m; } next.n=cur.n; if(!vis[next.s][next.n][next.m]) { next.level=cur.level+1; vis[next.s][next.n][next.m]=1; q.push(next); } if(judge(next)) return next.level; } //m->n if(cur.m&&n-cur.n>0) { //s->n if(cur.m>=(n-cur.n)) { next.m=cur.m-(n-cur.n); next.n=n; } else { next.m=0; next.n=cur.n+cur.m; } next.s=cur.s; if(!vis[next.s][next.n][next.m]) { next.level=cur.level+1;//要放入if裡 vis[next.s][next.n][next.m]=1; q.push(next); } if(judge(next)) return next.level; } } return -1; } int main() { while(~scanf("%d%d%d",&s,&n,&m)&&s+m+n) { int ans=bfs(); if(ans==-1) printf("NO\n"); else printf("%d\n",ans); } return 0; }