油瓶分油问题

来源:互联网 发布:新致软件股份有限公司 编辑:程序博客网 时间:2024/05/23 11:54

油瓶分油问题举例描述:

          例如:有三个大小不一样的且没有刻度的油瓶,其容量分别为12升、8升、5升;三个油瓶的初始油量为:12升、0升、0升;可以随意用某一瓶的油去灌满一瓶油,也可以把某一瓶的油全部倒入其他可以装下的一瓶油中,要求最后能得到一瓶装有6升的油。

编程要求:

         用户分三行分别输入各个油瓶的容量和各个油瓶的初始油量,最后一行再输入要求得到的目标油量。要求程序能够判断能否得到目标油量,入能则输出每一次倒油的步骤,不能得到则输出“不能得到目标油量”。只需要输出一中可行的分配方案即可。

        例如用户输入:

        12    8     5 (油瓶容量)

         12   0     0 (油瓶初始容量)

         6           要求得到的油量:


程序可以输出的一种方案是:

12 0 0

4 8 0

4 3 5

9 3 0

9 0 3

1 8 3

1 6 5

#include<iostream>#include<algorithm>#include<vector>#include<set>#include<iterator>using namespace std;/**油瓶分油问题*/vector<vector<int>> GetScheme(vector<int> & vols,vector<int> & stas,int des){vector<vector<int>> scheme;//解集scheme.push_back(stas);vector<int> is_full(vols.size(),0);vector<int> vec;for(int i = 0;i<vols.size();i++){if(vols[i]==stas[i])is_full[i] = 1;}//开始寻找解决方案while (true){int index_full = find(is_full.begin(),is_full.end(),1) - is_full.begin();if(index_full != is_full.size() )//如果找到有已满的油瓶先从满的油瓶开始分起可以避免走弯路{//让满油瓶从左往右找到第一个可以装油的油瓶开始分油int  i;for(i = 0;i<vols.size();i++) {if(is_full[i]!=1) {vec = stas;int need = vols[i] - stas[i];//先判断分配后的方案是否重复if(need>stas[index_full]){vec[i] += vec[index_full];vec[index_full] = 0;}else{vec[i]+=need;vec[index_full] -= need ;}if(find(scheme.begin(),scheme.end(),vec)==scheme.end())//不重复{if(need>stas[index_full]){stas[i] += stas[index_full];stas[index_full] = 0;}else{stas[i]+=need;is_full[i] = 1;stas[index_full] -= need ;}is_full[index_full] = 0;//保存scheme.push_back(vec);if(find(vec.begin(),vec.end(),des)!=vec.end())//如果已经找到目标油量则结束函数{return scheme ;}break;}}}if(i<vols.size())//如果满油瓶可以分配成功则直接进行下一次分配不需要再接着进行未满油瓶的分配{continue;}}//当没有满油瓶或者满油瓶没有分配成功时进行未满油瓶分配方案int i;for(i = 0;i<vols.size();i++){if(stas[i]>0&&is_full[i]!=1){//从左往右查找可以装油的油瓶int j;for ( j = 0;j < vols.size(); j++){if(is_full[j]!=1&&j!=i){vec = stas;int need = vols[j] - stas[j];//先判断分配后的方案是否重复if(need>stas[i]){vec[j] += vec[i];vec[i] = 0;}else{vec[j]+=need;vec[i] -= need ;}if(find(scheme.begin(),scheme.end(),vec)==scheme.end())//不重复{if(need>stas[i]){stas[j] += stas[i];stas[i] = 0;}else{stas[j]+=need;is_full[j] = 1;stas[i] -= need ;}is_full[i] = 0;//保存scheme.push_back(vec);if(find(vec.begin(),vec.end(),des)!=vec.end())//如果已经找到目标油量则结束函数{return  scheme;}break;}}}if(j<vols.size()){break;}}}//如果所有的方案都没有分配成功则为出现重复输出“不可能分配出目标油量”if(i>=vols.size()){scheme.clear();scheme.resize(0);return scheme;}}}int main(){vector<int> vlos;//油瓶的容量vector<int> stas;//油瓶当前油量//输入各个油瓶的容量copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(vlos));cin.clear();cin.sync();//输入当前各个油瓶的油量copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(stas));int de_state;//目标油量cin.clear();cin.sync();cin>>de_state;vector<vector<int>> revec =   GetScheme(vlos,stas,de_state);if(revec.size()==0){cout<<"不可能分配出目标油量"<<endl;}else{for (int i = 0; i < revec.size(); i++)       {   copy(revec[i].begin(),revec[i].end(),ostream_iterator<int>(cout," "));   cout<<endl;       }}return 0;}



1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 衣服上有火锅味怎么办 衣服沾上火锅味怎么办 做杨梅罐头里面好多小白虫怎么办 一地两检手续怎么办 剩米饭变干硬了怎么办 吃剩的米饭变硬怎么办 误食发热包的水怎么办 玻璃饭盒加热后盖子打不开怎么办 玻璃饭盒盖子被吸住了怎么办 微波炉加热饭盒盖子打不开怎么办 铁饭盒盖子打不开了怎么办 塑料玻璃饭盒打不开了怎么办 方便火锅没有发热包怎么办 加热包的水溢出怎么办 军用黄脸盆坏了怎么办 白瓷洗手盆发黄怎么办 挎包没有拉链东西容易掉怎么办 斜挎包肩带长了怎么办 3个月宝宝不吃奶怎么办 米饭扔厕所堵了怎么办 门过梁搭接不够怎么办 华为g7开不了机怎么办 警务通手机丢了怎么办 手机被伪基站覆盖怎么办 听了高频率声音怎么办 qq音乐签到没了怎么办 手机qq音乐不能播放怎么办 台式电脑放歌没有声音怎么办 微信图片上传大愎怎么办 行车记录仪内存卡丢了怎么办 投资项目失败lp的钱怎么办 无线网无ip分配怎么办 为什么电脑的暴风影音打不开怎么办 电枪充电板进水怎么办 捡到一颗子弹该怎么办 防弹衣只保护身体那手臂怎么办? 被子被宝宝尿湿怎么办 眼睛被子弹打了怎么办 gta5买了2套衣服怎么办 gta5车被摧毁了怎么办 gta5车被损坏了怎么办