標籤:style io os ar for sp on c amp
題目大意:有三個杯子,容量分別為a,b,c,一開始,a,b都是空的,只有c是滿的,現在開始倒水,一次倒水結束的條件是倒水的杯子倒完或者被倒的杯子倒滿,問要使得至少一個杯子有恰好d單位的水,最少的倒水量,如果d不可能,那麼就輸出最大的小於d的數dd,和最小倒水量
解題思路:只有三個杯子,用bfs搜尋達到d的最少水量,狀態得開二維,不然會逾時。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#define inf 0x3f3f3f3fusing namespace std;struct jug{ int L[3],s; friend bool operator<(jug a,jug b){ return a.s>b.s; }};int a,b,c,d;int vis[210][210];int S[3],cap[3],TS[3];int mark;int bfs(int d){ queue<jug> q; jug f; f.L[0]=0,f.L[1]=0,f.L[2]=c,f.s=0; q.push(f); vis[0][0]=1; int ret=inf; while(!q.empty()){ jug x=q.front(); q.pop(); if(x.L[0]==d||x.L[1]==d||x.L[2]==d){ if(x.s<ret) ret=x.s; continue; } if(x.s>=ret) continue; for(int i=0;i<3;i++){ if(!x.L[i]) continue; for(int j=0;j<3;j++){ if(i==j) continue; if(x.L[j]==cap[j]) continue; jug tmp=x; if(x.L[i]+x.L[j]>cap[j]){ tmp.L[i]=x.L[i]+x.L[j]-cap[j]; tmp.L[j]=cap[j]; tmp.s+=cap[j]-x.L[j]; }else{ tmp.L[i]=0; tmp.L[j]=x.L[i]+x.L[j]; tmp.s+=x.L[i]; } if(vis[tmp.L[0]][tmp.L[1]]!=mark){ vis[tmp.L[0]][tmp.L[1]]=mark; q.push(tmp); } } } } mark++; return ret;}void solve(){ cap[0]=a,cap[1]=b,cap[2]=c; if(d>max(max(a,b),c)) {printf("0 0\n");return;} memset(vis,-1,sizeof vis); mark=0; int ret=bfs(d); if(ret!=inf) printf("%d %d\n",ret,d); else{ for(int i=d-1;i>=0;i--){ ret=bfs(i); if(ret!=inf){ printf("%d %d\n",ret,i); break; } } }}int main(){ int T; scanf("%d",&T); for(int ca=1;ca<=T;ca++){ scanf("%d%d%d%d",&a,&b,&c,&d); solve(); } return 0;}
10603 Fill (BFS)