读书人

杭电1495 WRONG,该如何处理

发布时间: 2013-03-06 16:20:31 作者: rapoo

杭电1495 WRONG
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1495

每次倒,不管谁给谁倒,a这个存储量最小的瓶子,不是空的就是满的(即,最优解中不存在半满的情况——论证:如果出现了a没倒满的情况,倒给a的那个瓶子必然是b,而且现在是空的,另一个瓶子s.now等于s.max减掉a.now。继续往下倒,只能s->b。因为b大于a,b此时是满的,故依然不可能平分。接下来不论怎么倒,都会返回到第一次s满的时候一下就能倒出的情况)。好了,确定a的俩状态后,不论a处于何种状态,b跟s相互倒都是没有任何意义的。原因依然是可以回到第一次倒的情况。好了,现在就知道,中途中每次倒,必然是某一个瓶子(s或者b)把空的a倒满,然后a再倒给另一个瓶子(b或者s。因为a再倒回去,依然是没有任何意义的倒法)。把第一次倒分两种情况,分别讨论两个支路:



支路一:s->b;b->a;a->s;b->a;a->s;b->a;a->s..........

支路二:s->a;a->b;s->a;a->b;s->a;a->b........

则最优解如果存在,必然在这俩支路上。



不知道为啥,会wrong……有没有大牛帮忙指点一下?十分感谢……

//九度OJ 教程87 《非常可乐》
//http://ac.jobdu.com/problem.php?cid=1040&pid=86
#include <stdio.h>
#define MAXN 999999
typedef struct E{
int now;
int max;
}E;
int main()
{
E s,a,b,temp;
int count1,count2,flag1,flag2;
while(~scanf("%d %d %d",&s.max,&a.max,&b.max)&&s.max)
{
if(s.max&1){printf("NO\n");continue;}
if(a.max==b.max){printf("1\n");continue;}
s.now=s.max;//此下三行,恢复初始状态
a.now=b.now=count1=count2=0;
flag1=flag2=1;
if(a.max>b.max){temp=a;a=b;b=temp;}
s.now=s.max-b.max;
b.now=b.max;
count1++;
while(s.now!=b.now&&flag1)
{
b.now-=a.max;
s.now+=a.max;
count1+=2;
if(b.now<a.max)flag1=0;
}
if(!flag1)count1=MAXN;
s.now=s.max;//此下三行,恢复初始状态
a.now=b.now=0;
flag2=1;
while(s.now!=b.now&&flag2)
{
s.now-=a.max;
b.now+=a.max;
count2+=2;
if(s.now<b.now)flag2=0;
}
if(!flag2)count2=MAXN;
if(flag1||flag2)printf("%d\n",count1>count2?count2:count1);
else printf("NO\n");
}
return 0;
}
c 非常可乐
[解决办法]
10 3 7


10 0 0
3 0 7
3 3 4
6 0 4
6 3 1
9 0 1
9 1 0
2 1 7
2 3 5
5 0 5

读书人网 >软件架构设计

热点推荐