油瓶分油问题

油瓶分油问题举例描述:

例如:有三个大小不一样的且没有刻度的油瓶,其容量分别为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;
}

时间: 2024-08-03 15:04:54

油瓶分油问题的相关文章

倒油瓶问题(平分水问题)(bfs)

#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; int vist[105][105][105],a,b,c; struct node {     int a,b,c;     int step; }s[105]; int sum=0; void bfs() {     queue<node>q;     mem

用感光蓝油制作电路板

一.制作电路板的各种方法比较 有万能板.刀刻法.热转印法.油性笔画线.数控雕刻机雕刻.送专业PCB厂制作以及感光干膜法.感光湿膜(蓝油)法等等.万能板适合低密度电路,适合间距为100mil倍数的直插元件,所有的引线都要自己焊接,不需要打孔:刀刻法只适合有耐心和大量时间的人做点低密度小型电路:热转印可以制作复杂电路,转印质量和很多因素相关,线貌似不能做的太细,这个我没有自己试验过:油性笔(或者毛笔蘸油漆)画电路图显然也不太可能画出很细的线,线与线之间的距离也不好把握,用来做一些分立元件的模拟电路应

术率联与计定少代油命将们量至必标说arpxcr

家卫生健康委员会卫生应急办公室组织编制了公民卫生应急素养条目,并在"4·15全民国家安全教育日"发布.条目共12条,涉及突发公共卫生事件应对,突发事件紧急医学救援.中毒及核和辐射应急处置等基本知识和要求.期望通过发布公民卫生应急素养条目,进一步提高民众卫生应急素养,推进卫生应急社会参与工作,切实维护公民生命安全和身体健康. http://weibo.com/php_2018_04_20P/230927981149929492405898众钠讲都蹈CBM滋伤烟背 http://weibo

上交给国家!

闷油瓶从包裹里拿出了两只鬼玉玺.他掂量了一下,将其中一只交给吴邪,说:"你带着这只鬼玉玺回去,我只需要一只就够了.十年之后,如果你还记得我,你可以带着这个东西,打开那道青铜门.你可能还会在里面看到我.""不行!我不同意!"吴邪的声音有一些声嘶力竭,"两只都给我,我要上交给国家!"闷油瓶只好抚着青铜门看着吴邪坚定的眼神,点点头递上了另一只,「那我们只好就此别过了.」无邪愣了愣,似乎动摇了什么,他拉住了小哥的衣袖,声音颤抖:「你放心,我一定会带人来,

这样的大学

不知不觉,大学三年已经过去了,时间真的好快,人生苦短,我已经22岁了.我写这篇博客,不仅是为了完成作业,也是回首总结自己的整个大学生活. 我出生农村,父母都是农民出生.母亲初中文化,父亲高中文化.后来母亲当了家庭主妇,父亲做了商人.可以说,从小到大,我的家庭并没有那些文化熏陶之类的东西,并不是什么书香门第,也没有人教我怎么学,没有像这个博客C[1]的博主一样有什么父亲的书橱,经济条件的约束下也没有像这个博客A[2]的博主一样,小学毕业的暑假被家人送到市科委的计算机培训班进行计算机的启蒙,家庭对学

转: 罗辑思维:怎么样成为一个高手 文字版

感谢各位来到<罗辑思维>捧场 上一期节目我们隆重地给大家推荐了一个 付费的订阅产品 在我们罗辑思维开发的 得到APP里面 这个产品叫 精英日课 那主持它的是万维刚老师 因为我长期是他的读者和粉丝 所以我心知肚明 他出手开发的这个知识服务产品 品质有多高 所以我在美国专门跑了一趟 敦请他为我们的用户开发这个产品 所以上一期节目其实就是这个产品的广告 相信你也听出来了 特别不好意思 本期节目仍然是这个产品的广告 你看本期节目的题目 叫怎样才能成为一个高手 说实话 这期节目的策划案早就成型了 但是它

大海扬波,靠地球自转、潮汐和飓风

忠诚,就忠诚自己的土壤: 追求,就追求自己的理想. --引自友人的诗 这是一曲振奋人心的搏斗之歌.它的主旋律,就是祖国的荣誉高于一切! 人们把体育比喻为一个民族精神的橱窗.那么,就让我们打开中国女排这个小小的窗口,看一看我们中华民族应有的精神风貌吧! 挥动黄手绢唱的歌 公元一千九百七十七年深秋.苍茫的暮色,笼罩着日本的商业都市大阪. 中国女排姑娘们乘坐的大型轿车,顺着五光十色的街道缓缓向前行驶. 多彩的夜景,与中国姑娘们喜悦的心境是相吻合的.今晚,一九七七年世界杯排球赛进入最后一个高潮--发奖.

盗墓笔记读后感

很久没动笔了,估计生疏了许多. 断断续续,花了将近两周的时间看完了盗墓笔记,一开始感觉的是惊险.刺激,超级有画面感的描述方式,让我久久沉浸于其中.再往后,越看越有一种淡淡的伤萦绕在情节中. 主人公吴邪是那种烂好人的性格,天性纯良,然而一次次的盗墓,一次次谜底的揭穿,个中情节的曲折和相关人物的决绝狠戾让他一直挣扎.痛苦,每一次他的决定都会带来死亡,而他最不愿意看到的是因为自己导致别人的死亡.从来他都不是为自己而活,活在别人的世界,揭露别人的真相,他拼了命的帮小哥寻找身世,了解小哥的故事.家族,即使

塑料脱标机的独特优势

塑料脱标机专业对于国产PET矿泉水瓶.饮料瓶.油瓶等中空瓶瓶体与标签的高效别离而规划,其构造合理,性价比极高.顺鑫出产的塑料脱标机采用全铜线电机,高效节能,塑料脱标机刀片规划合理,动定双刀有效合作,脱标洁净度达90%以上,能够大大减少人工的投入,进步出产能力. 塑料脱标机特色: 1.剥纸作用好,纸和瓶别离洁净,不伤瓶体,不变色. 2.脱标后的矿泉水瓶成色通明,划痕少,损耗低,机器作业噪音小,作业噪音不会超越75分贝. 3.塑料脱标机依托拌和轴上焊接拌和桨来翻动物料,这种方式可使物料被水平散布,所