uva 10603 Fill

来源:互联网 发布:sql row_number() over 编辑:程序博客网 时间:2024/06/06 00:35

题目:Fill


题意:有3个容积为a,b,c的杯子,最初a、b为空,c中装满水。每次可以从一个杯子向另一个杯子倒水,但只有把一个杯子倒空或把另一个杯子倒满时才能停止。如果要使其中一个杯子中有d升水,求最少倒水的的体积。若无法满足 ,则目标水量要比d小且和d尽量接近。


思路:

bfs遍历。

由于所说为体积最小,所以要一直将图遍历完才能遭到最优解。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<map>#include<algorithm>#include<sstream>using namespace std;#define n 3struct Node {int x[n];Node() {}Node(int one,int two,int three) {x[0]=one,x[1]=two,x[2]=three;}bool operator <(const Node& other) const {for(int i=0; i<n; i++) {if(x[i]<other.x[i]) return true;if(x[i]>other.x[i]) return false;}return false;}};int d;Node M;struct Pair {int step,D;Pair() {step=0,D=0;}Pair(int x[],int S) {step=S;D=d;for(int i=0; i<n; i++) {if(x[i]<=d) D=min(D,d-x[i]);}}Pair(int one,int two) {step=one,D=two;}bool operator <(const Pair& other) const {if(D<other.D||(D==other.D&&step<other.step)) return true;return false;}};void bfs(Node IN,map<Node,Pair>& mp) {vector<Node> que;int t=0;que.push_back(IN);mp[IN]=Pair(IN.x,0);while(t<que.size()) {Node head=que[t];t++;for(int i=0; i<n; i++)for(int j=0; j<n; j++) if(i!=j&&head.x[i]!=0&&head.x[j]!=M.x[j]) {Node ch=head;int move;if(ch.x[i]>=M.x[j]-ch.x[j]) move=M.x[j]-ch.x[j];else move=ch.x[i];ch.x[i]-=move,ch.x[j]+=move;if(!mp.count(ch)||mp[head].step+move<mp[ch].step) {que.push_back(ch);mp[ch]=Pair(ch.x,mp[head].step+move);}}}}void find(map<Node,Pair> mp) {vector<Pair> vec;for(map<Node,Pair>::iterator it=mp.begin(); it!=mp.end(); it++) vec.push_back(it->second);sort(vec.begin(),vec.end());printf("%d %d\n",vec[0].step,d-vec[0].D);}int main() {int T;scanf("%d",&T);while(T--) {int A,B,C;scanf("%d%d%d%d",&A,&B,&C,&d);M=Node(A,B,C);map<Node,Pair> mp;bfs(Node(0,0,C),mp);find(mp);}return 0;}


原创粉丝点击