一开始的时候, 直接考虑dfs,开一个整形数组初始化0,用于存储vc的状态。 输入一组状态, 根据三个杯子各自的容量大于0的时候, 进行向其他杯子倒水的操作,操作时先判断这三个杯子的容量状态是否出现过, 出现过的话 就中止操作, 但是给出的数据范围是(0~4000)三个杯子的话进行标记就是4000的三次方, 经朋友提醒采用set,建立结构体(需要operator<), 一开始将初始状态存入set中,后续在dfs的时候每次先判断,查找==set,end(); , 表明没有找到, 将这个状态插入, 然后对应整形数组下标的值设为1 ;最后统计整形数组中 1的个数;
后面想到,三组数据, 大概就是大中小这样的关系(局部等于就暂时忽略)。1,vc是最小的, 则只可能有两种状态,满 或者0。2, vc是最大的, 则根据另外两个是否相同, 分别是三种或四种。3, vc介于两者之间的时候, 实质是vc不断的减去min来进行更新。
中间的细节自己推断一下,比如有的为0, 或者某两个相等的时候,下面代码中有介绍。
#include <iostream>
using namespace std;
int main()
{
int va, vb, vc;
while(scanf("%d%d%d", &va, &vb, &vc) != EOF){
//没有一个为0
if(va * vb * vc != 0){
//VC是最小的 则状态仅有满的或空的
if(vc <= va && vc <= vb) printf("2\n");
//VC是最大的
else if(vc>va && vc > vb){
//另外两个容积相等 无论 两者之和小于或大于等于vc
// 都是三种结果 最后一种为0 或者 VC-2VA
if(va == vb) printf("3\n");
else{
//另外两个大小不同 则是VC VC- VA vc-vb
// 0 或 vc- va - vb
printf("4\n");
}
}
//最后一种情况 VC介于两者之间的时候,除去满和空的状态
//一直在利用最小的杯子对其做减法 每减去一次 就更新
//根据是否整除 进行更新
else{
int minn;
if(va < vb)
{
minn = va;
}
else{
minn = vb;
}
int temp = vc / minn;
if(vc % minn == 0){
printf("%d", 1 + temp);
}
else{
printf("%d", 2 + temp);
}
}
}
else{
//仅有0的状态
if(vc==0) printf("1\n");
else{
//其余两者为0 则只有1
if(va==0 && vb ==0) printf("1\n");
//其余两者有一个为0, 则只能更新一次 满的 或满减去非零的
else{
printf("2\n");
}
}
}
}
return 0;
}