高分:分油问题,c++怎么编程?

有三个大小不等的,没有刻度的瓶子,分别能装x,y,z升水。开始时,x装满水,y和z两个为空。要求找出一种步骤最少的分水方法,在某个桶上分出t升水。(为方便,假设x、y、z、t都为整数)
要求

① 输入为三个瓶子的装水量(例如分别是10、7、2L)和需要分出的水量t 升(如4 L)。
② 若能够分得t升水,输出分水的详细过程,要求分水步骤数最少。
③ 若不能分得t升水,输出“不可能”。
用C++编程,要求完整能直接运行

#include <stdio.h>
#include <string.h>
int vol1,vol2,vol3,cur1,cur2,cur3,flag=0,goal,curb1,curb2,curb3;
int map[100][100][100];
int x[10000]; //记录每一步的倒油操作,1到2表示为1,1到3表示为2,2到1表示为3,2到3表示为4,3到1表示为5,3到2表示为6 
void push(int *t1, int *t2,int v2) //把 *t1和*t2为当前油量,v2为*t2所在容器的容量。 
{if(  v2>*t1+*t2){*t2=*t2+*t1;*t1=0;}
 else {  *t2=*t2+*t1;*t1=*t2-v2;*t2=v2;}
}
void print(int step)
{printf("%d %d %d\n",curb1,curb2,curb3);
  for(int i=1;  i<step;i++)
  switch(x[i])
   { case 1: 
              push(&curb1,&curb2,vol2);
            printf("%d %d %d\n",curb1,curb2,curb3);
            break;
     case 2: 
            push(&curb1,&curb3,vol3);
            printf("%d %d %d\n",curb1,curb2,curb3);
            break;
     case 3: 
            push(&curb2,&curb1,vol1);
            printf("%d %d %d\n",curb1,curb2,curb3);
            break;
     case 4: 
            push(&curb2,&curb3,vol3);
            printf("%d %d %d\n",curb1,curb2,curb3);
            break;
     case 5: 
            push(&curb3,&curb1,vol1);
            printf("%d %d %d\n",curb1,curb2,curb3);
            break;
     case 6: 
            push(&curb3,&curb2,vol2);
            printf("%d %d %d\n",curb1,curb2,curb3);
            break;
     
   }
     
}
void backtrack(int step)
{ int t1=cur1,t2=cur2,t3=cur3;  
   if(flag) return;
   if(  t1==goal||t2==goal||t3==goal)
    { print(step);flag=1;return; }
  //开始尝试1倒到2 
    push(&cur1,&cur2,vol2);
    if(!map[cur1][cur2][cur3])
    {x[step]=1;map[cur1][cur2][cur3]=1;
     backtrack(step+1); 
    }
    cur1=t1;cur2=t2;cur3=t3;
   //结束1倒到2,恢复各容器的原来油量 
  //开始尝试1倒到3 
      push(&cur1,&cur3,vol3);
    if(!map[cur1][cur2][cur3])
    {  x[step]=2;map[cur1][cur2][cur3]=1;
         backtrack(step+1); 
    }
    cur1=t1;cur2=t2;cur3=t3;
  //结束1倒到3,恢复各容器的原来油量 
  //开始尝试2倒到1 
    push(&cur2,&cur1,vol1);
    if(!map[cur1][cur2][cur3])
    {x[step]=3;map[cur1][cur2][cur3]=1;
     backtrack(step+1); 
    }
    cur1=t1;cur2=t2;cur3=t3;
  //结束2倒到1,恢复各容器的原来油量
  //开始尝试2倒到3
    push(&cur2,&cur3,vol3);
    if(!map[cur1][cur2][cur3])
    {x[step]=4;map[cur1][cur2][cur3]=1;
     backtrack(step+1); 
    }
    cur1=t1;cur2=t2;cur3=t3;
  //结束2倒到3,恢复各容器的原来油量
  //开始尝试3倒到1 
    push(&cur3,&cur1,vol1);
    if(!map[cur1][cur2][cur3])
    {x[step]=5;map[cur1][cur2][cur3]=1;
     backtrack(step+1); 
    }
    cur1=t1;cur2=t2;cur3=t3;
  //结束3倒到1,恢复各容器的原来油量
  //开始尝试3倒到2 
    push(&cur3,&cur2,vol2);
    if(!map[cur1][cur2][cur3])
    {x[step]=6;map[cur1][cur2][cur3]=1;
     backtrack(step+1); 
    }
    cur1=t1;cur2=t2;cur3=t3;
  //结束3倒到2,恢复各容器的原来油量
}
  
int main()
{scanf("%d%d%d%d%d%d%d",&vol1,&vol2,&vol3,&cur1,&cur2,&cur3,&goal);
 memset(map,0,sizeof(map));
 map[cur1][cur2][cur3]=1;
   curb1=cur1;curb2=cur2;curb3=cur3;
 backtrack(1);
 if(  !flag)
 printf("impossible");
}


输入:


3行
第1行是3个整数,由大到小,表示3个容器的容量
第1行是3个整数,表示3个容器的原有油量
第3行是1个整数,表示要求得到的油量(放在哪个容器里得到都可以)


输出:


实现过程中的各个状态(即各个容器的油量)。答案不唯一。
如果没有可能实现,则输出:“impossible”。

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-06-21
今天实验了一下,写出了一半吧。就是这个求最优解就太困难了,而且记录求解路径很困难。这种题遇到不是一次两次了,有喜欢的大家一起交流交流经验。
第2个回答  2013-06-21
能强行写出,不过程序优化就等等吧

分油问题与编程C++,,高分悬赏 要有解释 详细点
if(a>=(7-b))\/\/如果a中的油量大于b中需要的油量,那么就可以把b倒满。{ a = a-(7-b);b = 7;} if(a<(7-b))\/\/如果a中的油量小于b中需要的油量,那么a将要倒空。{ b = b+a;a = 0;} } \/\/以下的注释和上一个差不多,就不写了 void fun_2()\/\/a向c中倒油 { if(...

汽车加油问题(用C语言或C++)
int n,m,i,j,k,d[1000],dis,count,n2;while((scanf("%d%d",&n,&k))!=EOF){ dis=0;count=0;for(i=0;i<k+1;i++){scanf("%d",&d[i]);dis+=d[i];} if(dis<=n){ printf("0\\n");} else{ j=0;for(i=1;i<k+1;i++)if(d[0]==d[i]&&d[0]==n)j++;if...

...汽车加油行驶问题 可以在VC++ 6.0上运行的C++代码,再不行C也可以...
0, 0,0, -1, 0,1, 0, 0,0, 1, 0};class point {public:int x, y, k, cost;};bool operator<(const point& a, const point& b) {return a.cost > b.cost;}

讨教一个C++ 编程作业
5:装满油,开到125公里处,储存250公升油,开回起点;6:装满油,开到125公里处,取出125公升油,开到250公里处,储存250公升油,开回到125公里处,取出125公升油,开回起点;7:装满油,开到125公里处,储存250公升油,开回起点;8:装满油,开到125公里处,取出125公升油,开到250公里处,取出125公...

c++邮票组合问题?
纯粹的数学组合问题。4 张三分邮票, 3 张五分邮票,有几种组合(要求至少有 1 张)。三分邮票可以 0 张、1 张、2 张、3 张、4 张,总共 5 种方案,五分邮票可以 0 张、1 张、2 张、3 张,总共 4 种方案。答案就是 4 * 5,再减去(0, 0)这一不符合题意的组合。

c++ 很简单的问题,但我不懂
我们来换算一下看看:1 加仑 = 3.785 升 (题中给的数字有问题,不是3.875)19 英里 = 19\/62.14*100 公里 所以, 19 mpg 就相当于 3.785升每(19\/62.14*100)公里 则每100公里消耗的汽油量为: (3.785\/(19\/62.14*100))*100 = 12.4 升 设M表示美国风格的耗油量,E表示欧洲风格...

怎么学好C++,我不知道学这个有什么用,老师说编程什么的,可是除了调试成 ...
一般来说,任何底层组件都会向更上层提供适当的接口以调用其各种功能,而且这些调用都能够在高层语言的某个库中找到。说到这里,你对C++中的很多类库熟悉吗?那些类库正是C++实现复杂功能的基本元素。不仅是C++,任何编程语言都会提供与系统底层功能相关的库函数。要不,怎么干事呢?就拿操作系统来说,如果...

计算机编程语言C C++ C#如果要学习的话 应该从哪里学起?要具备哪些基础...
学习编程,一上来会面临两类问题:理解语言、如何些程序。如果是看题目如《VC++XXXXX》的书,讲的更多的是如果使用编程环境给你提供的支持,如怎么弹出对话框,怎么显示图片,怎么响应鼠标操作。这部分的书推荐 微软技术丛书系列。如果看的是《C++程序设计》类似名字的书,则主要讲的是语言的语法本身,学...

C++基础怎样学习?
难学是因为C++语法本身很复杂,功能很强大,支持的编程范式也很多,每种语法糖又有很多特例和不推荐使用的设计风格,因此对语法的介绍必须细腻全面,只是要注意介绍语法糖时要以写程序为目的,而不是为了语法而语法。作者时刻让你知道,每种C++语法都有何用处,应该怎么用。而易用则是因为C++标准库(特别...

关于学习C++ 迷茫
2、有了一定基础编程经验以后,可以在网上找一些其他人写的稍微大型一点的系统,一般都是由源码的,边看边学,不懂就查资料,或者在网上发帖提问。照猫画虎学习一段时间,把别人好的思想和思路学懂,学透,然后自己尝试开发一个类似的东西,不去看源代码,完全自己写。不懂了就查。3、经过点2的锻炼...

相似回答