题意:有三个没有刻度的水壶,容量分别为a,b和c(单位为升,都是<=200的正整数)。初始时前两个水壶是空的,而第三个装满了水。每次可以从一个水壶往一个水壶里倒水,直到一个水壶倒空或者另一个水壶倒满。为了让某个水壶恰好有d升水,至少要倒多少升的水?如果无解,找一个小于且最接近d的d’代替d。
分析:
本题最多的状态数不超过(A+1)*(B+1),故BFS所有状态即可.
// File Name: 10603.cpp // Author: Zlbing // Created Time: 2013/4/16 16:52:33 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) const int MAXN=205; int G[MAXN][MAXN][MAXN]; int A,B,C; int V[MAXN]; struct node{ int a,b,c,h; bool operator <(const node& r)const{ return h>r.h; } }; void bfs(node s,int d) { priority_queue<node> Q; Q.push(s); int k; while(!Q.empty()) { node t=Q.top(); Q.pop(); if(V[t.a]==-1) V[t.a]=t.h; else V[t.a]=min(V[t.a],t.h); if(V[t.b]==-1) V[t.b]=t.h; else V[t.b]=min(V[t.b],t.h); if(V[t.c]==-1) V[t.c]=t.h; else V[t.c]=min(V[t.c],t.h); node tt; int aa=A-t.a; if(aa>0) { k=min(aa,t.b); tt.b=t.b-k;tt.a=t.a+k; tt.c=t.c;tt.h=t.h+k; if(G[tt.a][tt.b][tt.c]==-1||tt.h<G[tt.a][tt.b][tt.c]) { Q.push(tt); G[tt.a][tt.b][tt.c]=tt.h; } k=min(aa,t.c); tt.c=t.c-k;tt.a=t.a+k; tt.b=t.b;tt.h=t.h+k; if(G[tt.a][tt.b][tt.c]==-1||tt.h<G[tt.a][tt.b][tt.c]) { Q.push(tt); G[tt.a][tt.b][tt.c]=tt.h; } } int bb=B-t.b; if(bb>0) { k=min(bb,t.a); tt.a=t.a-k;tt.b=t.b+k; tt.c=t.c;tt.h=t.h+k; if(G[tt.a][tt.b][tt.c]==-1||tt.h<G[tt.a][tt.b][tt.c]) { Q.push(tt); G[tt.a][tt.b][tt.c]=tt.h; } k=min(bb,t.c); tt.c=t.c-k;tt.b=t.b+k; tt.a=t.a;tt.h=t.h+k; if(G[tt.a][tt.b][tt.c]==-1||tt.h<G[tt.a][tt.b][tt.c]) { Q.push(tt); G[tt.a][tt.b][tt.c]=tt.h; } } int cc=C-t.c; if(cc>0) { k=min(cc,t.a); tt.a=t.a-k;tt.c=t.c+k; tt.b=t.b;tt.h=t.h+k; if(G[tt.a][tt.b][tt.c]==-1||tt.h<G[tt.a][tt.b][tt.c]) { Q.push(tt); G[tt.a][tt.b][tt.c]=tt.h; } k=min(cc,t.b); tt.b=t.b-k;tt.c=t.c+k; tt.a=t.a;tt.h=t.h+k; if(G[tt.a][tt.b][tt.c]==-1||tt.h<G[tt.a][tt.b][tt.c]) { Q.push(tt); G[tt.a][tt.b][tt.c]=tt.h; } } } for(int i=d;i>=0;i--) if(V[i]!=-1){ printf("%d %d\n",V[i],i); break; } } int main() { int T; scanf("%d",&T); while(T--) { int d; scanf("%d%d%d%d",&A,&B,&C,&d); CL(G,-1); CL(V,-1); V[C]=0; V[0]=0; node t; t.a=0,t.b=0,t.c=C,t.h=0; bfs(t,d); } return 0; }