| 网站首页 | 业界新闻 | 群组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 编程论坛
大量收QQ微信精准粉/交友粉,非诚勿扰千里之行 始于足下
共有 2459 人关注过本帖, 1 人收藏
标题:[抄道题] 4瓶盖换一啤酒,两空瓶换一啤酒,则已有n啤酒的情况下,最多能喝到 ...
只看楼主 加入收藏
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:266
帖 子:5829
专家分:33315
注 册:2011-1-18
结帖率:90.91%
  已结贴   问题点数:100  回复次数:8   
[抄道题] 4瓶盖换一啤酒,两空瓶换一啤酒,则已有n啤酒的情况下,最多能喝到多少瓶啤酒?
四个瓶盖能换一瓶啤酒,两个酒瓶也能换一瓶啤酒。
现在已经买了n瓶啤酒,那么共能喝到多少瓶啤酒?
(不允许 2个瓶盖+1个酒瓶 换酒等情况)
搜索更多相关主题的帖子: 啤酒  一瓶  
2015-12-18 16:29
wmf2014
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:153
帖 子:1704
专家分:9500
注 册:2014-12-6
  得分:33 
我先用笨办法,抛砖引玉
程序代码:
#include<iostream>
using namespace std;
void main()
{
    int n,i,j,s;
    cin>>n;
    for(s=0,i=0,j=0;n||i>=4||j>=2;n--)
    {
        if(i==4)
        {
            i=0;
            n++;
        }
        if(j==2)
        {
            j=0;
            n++;
        }
        s++;
        i++;
        j++;
    }
    cout<<"最多可喝"<<s<<",还剩瓶盖"<<i<<",剩瓶子"<<j<<endl;
}


能编个毛线衣吗?
2015-12-18 16:52
wengbin
Rank: 10Rank: 10Rank: 10
来 自:陕西西安
等 级:贵宾
威 望:19
帖 子:370
专家分:1846
注 册:2015-5-8
  得分:33 
程序代码:
#include<iostream>
using namespace std;
/*
准赊账的前提下:
设一瓶酒中,瓶子价值为x,盖子价值为y,水价值为z
==>2x=x+y+z
   4y=x+y+z
==>x=2z,意味着空瓶的价值为水的2倍
   y=z,意味着盖子的价值与水相同
   则一瓶酒的价值最终可以低4份水。
   所以n瓶酒可以换4n瓶酒,且最终没有盖子或瓶子的剩余。
*/
int ZhunShe(int n)
{
    return 4 * n;
}
/*
不准赊账时:思路是用递归的方法
n瓶酒相应会产生n瓶n盖,然后以盖和瓶换洒(相应减掉瓶子和盖子数)
换得酒的同时得到盖和瓶(加上相应的瓶子和盖),直到瓶子的个数小于2
且盖子的个数小于4;
*/
int BuShe(int m, int n, int k);
int TOTAL(int N)
{
    return BuShe(N, N, N);
}
int BuShe(int m,int n,int k)
{
    int total=m,bottle=n, top=k;
    int tmp_total = 0;
    if(bottle>1||top>3)
    {
        int tmp_total = bottle / 2 + top / 4;    //换得的酒
        int tmp_bottle = bottle % 2;            //剩余的瓶子
        int tmp_top = top % 4;                    //剩余的盖子
        cout << "换酒前共有" << total << "酒," << bottle << "" << top << "盖\n";
        cout << "可换" << tmp_total << "酒,剩余" << tmp_bottle << "" << tmp_top << "盖\n";
        total += tmp_total;
        bottle = tmp_bottle + tmp_total;
        top = tmp_top + tmp_total;
        cout << "换酒后共有" << total << "酒," << bottle << "" << top << "盖\n\n";
        BuShe(total, bottle, top);
    }
    else
        return total;
    //return total;一加这句就错了,不加则有一个警告说不是所有的控件路径都返回值,不知道怎么改,请教授一下。
}


int main()
{
    int N = 5;
    int total=TOTAL(N);
    cout << "total:"<<total<<endl;
    system("pause");
    return 0;
}

整理一下是这样的(看的能清爽点):
程序代码:
#include<iostream>
using namespace std;
int ZhunShe(int n);                    //可以赊账时
int TOTAL(int N);
int BuShe(int m, int n, int k);        //不可赊账时
/*
---------------函数实现-----------------------*/
int ZhunShe(int n)
{
    return 4 * n;
}

int TOTAL(int N)
{
    return BuShe(N, N, N);
}
int BuShe(int m,int n,int k)
{
    int total=m,bottle=n, top=k;
    if(bottle>1||top>3)
    {
        total = total+(n / 2 + k / 4);
        bottle = bottle - (n / 2) * 2 + (n / 2 + k / 4);
        top = top - (k / 4) * 4 + (n / 2 + k / 4);
        return BuShe(total, bottle, top);//稍稍改下
    }
    else
        return total;
    return total;//现在有这句可以了,尽管已经用存在这句了。
}


int main()
{
    int N = 5;
    int total=TOTAL(N);
    cout << "total:"<<total<<endl;
    system("pause");
    return 0;
}


[此贴子已经被作者于2015-12-21 08:37编辑过]

2015-12-19 01:12
wmf2014
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:153
帖 子:1704
专家分:9500
注 册:2014-12-6
  得分:34 
循环也很容易改为递归,如用递归的话,则不好知道最后剩下的瓶子和瓶盖数目,递归代码如下:
程序代码:
#include<iostream>
using namespace std;
int beer(int n,int g,int p)
{
    if(n<=0&&g<4&&p<2)return 0;
    else
    {
        n=n+(g==4)+(p==2);
        if(g==4)g=0;
        if(p==2)p=0;
        return 1+beer(--n,++g,++p);
    }
}
void main()
{
    int n;
    cin>>n;
    cout<<"原始有"<<n<<"瓶酒,最多可喝:"<<beer(n,0,0)<<endl;
}



[此贴子已经被作者于2015-12-19 15:12编辑过]


能编个毛线衣吗?
2015-12-19 15:07
wengbin
Rank: 10Rank: 10Rank: 10
来 自:陕西西安
等 级:贵宾
威 望:19
帖 子:370
专家分:1846
注 册:2015-5-8
  得分:0 
回复 4楼 wmf2014
看版主们的代码总感觉是在看艺术品一样,简洁,直接,期待我也有一天能这样呀
2015-12-21 08:35
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:266
帖 子:5829
专家分:33315
注 册:2011-1-18
  得分:0 
当n>1时,4*n-5;当n=1时,1。
不知道对不对?


[此贴子已经被作者于2015-12-21 12:31编辑过]

2015-12-21 08:39
阿文fire
Rank: 2
等 级:论坛游民
威 望:1
帖 子:11
专家分:58
注 册:2009-7-7
  得分:0 
程序代码:
#include <stdio.h>

int main()
{
    unsigned buy;
    printf("买啤酒x瓶:");
    scanf("%u",&buy);
    for(unsigned drink = 2*buy; drink < 4*buy; drink++) //! 喝酒瓶数处于2倍买酒瓶数和4倍买酒瓶数之间
    {
        unsigned lib = drink%4;
        unsigned bottle = 1;//!瓶一定是剩1个
        if(4*buy-2*bottle-lib == drink)
        {
            printf("喝了%u瓶,剩%u瓶%u盖.\n",drink,bottle,lib);
            return 0;
        }
 



[此贴子已经被作者于2015-12-29 21:35编辑过]

2015-12-21 11:26
wengbin
Rank: 10Rank: 10Rank: 10
来 自:陕西西安
等 级:贵宾
威 望:19
帖 子:370
专家分:1846
注 册:2015-5-8
  得分:0 
回复 6楼 rjsp
已经试过好多,目前没有发现反例,应该是了,在网上也见到了相关证明的例子,能喝4n-5瓶,最后一定会剩下1瓶3盖....

[此贴子已经被作者于2015-12-21 15:04编辑过]

2015-12-21 14:56
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:266
帖 子:5829
专家分:33315
注 册:2011-1-18
  得分:0 
回复 8楼 wengbin
谢谢
f(1)时,剩1瓶1盖
f(2)时,剩1瓶3盖
f(3)时,等同于f(1)+f(2),即剩2瓶4盖,再继续,最终剩1瓶3盖
其后f(n)都等同于f(1)+f(n-1),即剩2瓶4盖,再继续,最终剩1瓶3盖
2015-12-21 15:09







关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027759 second(s), 9 queries.
Copyright©2004-2018, BCCN.NET, All Rights Reserved