倒水问题求编程,你给力我给分!
一个12升的容器装满了水,希望把他分成相等的两份,但手边只有一个8升的容器和一个5升的容器,问咱怎么倒才能达到目的,试编程写出所有的倒水方案,并找到倒水次数最少的一种方案。方案1. 12升 8升 5升
12 0 0
4 8 0
4 3 5
9 3 0
9 0 3
1 8 3
1 6 5
6 6 0
还有其他方案。
程序代码:#include <stdio.h>
/***************************************************************/
int volume[] = {12, 8, 5}; // 3个容器的体积
int from[] = {0, 0, 1, 1, 2, 2}; // 定义12L,8L,5L分别为0号1号2号
int to[] = {1, 2, 0, 2, 0, 1}; // from --> to
int step[50][3]; // 定义一个二维数组存放每倒一次的状态state[]
int step_count = 0; // 记录每种独立方案所需要倒水的次数
static int count = 0; // 记录总的方案数
int i; // 循环变量
/***************************************************************/
void pour_water(int state[], int f, int t); // 倒一次水state发生改变
void step_water(int state[]); // 每倒一次水后记录state在二维数组中
int appeared(int state[]); // 查看独立方案中是否有相同的状态出现,避免死循环
void output(); // 如果方案可行打印其步骤
void GO(int state[]); // 在初始状态下进行倒水
/***************************************************************/
int main(void)
{
int init_state[] = {12, 0, 0}; // 初始化状态为 12, 0, 0
GO(init_state); // 寻求合理的方案
if (count == 0) // 我设置了个观察状态,很遗憾Impossible都无法打印出来
printf("\nImpossible!\n");
return 0;
}
/***************************************************************/
void pour_water(int state[], int f, int t)
{
int sub = volume[t] - state[t];
if (state[f] < sub)
{
state[t] += state[f];
state[f] = 0;
}
else
{
state[t] = volume[t];
state[f] -= sub;
}
}
/***************************************************************/
void step_water(int state[])
{
step[step_count][0] = state[0];
step[step_count][1] = state[1];
step[step_count][2] = state[2];
step_count++;
}
int appeared(int state[])
{
for (i = 0; i < step_count; i++)
if ((state[0] == step[i][0])
&& (state[1] ==step[i][1])
&& (state[2] == step[i][2]))
return 1;
else
return 0;
}
/***************************************************************/
void output()
{
printf("step\t12L\t8L\t5L\n");
printf("---------------------------------------------\n");
for (i = 0; i < step_count; i++)
printf("%d\t%d\t%d\t%d\n", i, step[i][0], step[i][1], step[i][2]);
printf("\n");
}
/***************************************************************/
void GO(int state[])
{
int v12 = state[0];
int v8 = state[1];
int v5 = state[2];
step_water(state); // 记录状态
if (v12 == 6 && v8 == 6 && v5 == 0)
{
output(); // 得到合符要求的状态则打印
count++; // 方案数++
return;
}
for (i = 0; i < 6; i++) // from --> to 有6种,遍历开始
{
if (state[from[i]] == 0 )
continue; // 剔除空容器,其不能作为输出瓶
pour_water(state, from[i], to[i]); // 找到一个合法的输出瓶,倒水,使state发生改变
if (!appeared(state)) // 与前面的状态相比较,没有重复则递归调用
GO(state);
else // 状态重复
continue; // 剔除
state[0] = v12;
state[1] = v8;
state[2] = v5; // 状态复原,保证循环中下一个i的初始状态
}
}

