这问题之前看过...那时写了个可以计算有N人数,买X送Y,求最少购买数的程序...当然...有比这更好的程序...如果谁有的话,请POST出来交流一下...太久了...现在不想做这程序的优化工作...
之前看到的贴中,有人POST出了数学解法,不过那是对于搂主的问题,已证明了那个数学解法不能解同一类问题...
[CODE]
#include <cstdlib>
#include <iostream>
using namespace std;
void least_x( const int, const int, const int );
int main( int argc, char *argv[] )
{
int x, y, s;
do{
cout << "请输入人数:"; cin >> s;
cout << "请分别输入有多少瓶子送多少水的数,如 5 2:"; cin >> x >> y;
if( y >= x )
cout << "你做亏本生意啦!请重新输入吧!" << endl;
else
{
cout << endl;
break;
}
}while(1);
least_x( x, y, s );
system("PAUSE");
return EXIT_SUCCESS;
}
void least_x( const int x, const int y, const int s )
{
int _x = 0, //累积购买数
_y = 0, //累积获赠数
_s = 0, //累积总数
_t = 0, //空瓶剩余数
_tmp = 0, //存储每次获得的赠送数
_more = 0; //多出来的赠品水
while( _s < s ) //判断累计总数是否大于计划购买总数,如果大于等于,则表明全部人都又有水了
{
if( (s-_s>=x+y) && (_t+y<x) ) //判断剩下没买的是否大于购买数加赠送数且空瓶数是否不足以赠送水
{ //如果上述均为真,则只要让其相对增加规定量即可
_t+=y; _x+=x;
_y+=y; _s+=(x+y);
if( _s >= s )
_s = s;
}
else if( (s-_s>=x+y) && (_t+y>=x) ) //判断与上述差不多
{ //如果上述为真,则需要求得买这次水总共赠送了多少瓶水
_x+=x; _t+=y;
_tmp+=y; _t=_t%x+y;
while( _t >= x )
{
_tmp+=y; _t=_t%x+y;
}
_y += (y + _tmp); _s = _y + _x; _tmp = 0;
if( _s >= s )
_s = s;
}
else if( (s-_s<x+y) && (_t+s-_s<x) ) //判断与上述差不多,至于第二判断,是判断空瓶数加上剩余数是否大
//于可赠送数
{ //如果为真,则让购买数加上剩余数,且可以确定,已经购买够水了
_x += s - _s; _s = s;
}
else if( (s-_s<x+y) && (_t+s-_s>=x) ) //判断与上述差不多
{ //如果目前空瓶数加上剩余数后,是否满足赠送数
for( int i = 1; i <= s - _s; i++ ) //如果满足,则说明在1->s-_s间,存在一个最小数,使得购买数最小
{
_t+=1; //递增查找
if( _t>=x ) //如果空瓶数大于可赠送数的话,则说明空瓶数换得新水瓶后,可能全部人都有水
{
_tmp+=y; _t=_t%x+y; //求得空瓶数可以换得多少新水瓶
while( _t >= x )
{
_tmp+=y; _t=_t%x+y;
}
if( _tmp >= s-_s - i ) //如果新水瓶加上购买大于等于剩余数的话,则说明已经买够水
{ //让购买数加上这次购买数,则得到最少购买数,同时,求得总共赠送了多少瓶水
_y+=_tmp;
_x+=i; _s=s; break;
}
}
}
_tmp = 0;
}
if( _y - (s - _x) > 0 )
_more = _y - (s - _x);
else
_more = 0;
cout << "总购买数为:" << _x << endl
<< "赠品水共有:" << _y << endl
<< "多出的赠品水有:" << _more << endl
<< "共需要水:" << _s << endl
<< "共有水: " << _x + _y << endl << endl;
}
cout <<"至少买 " << _x << " 瓶水!" << endl;
}
[/CODE]
[此贴子已经被作者于2007-8-12 23:39:45编辑过]