第三届蓝桥杯软件类省赛真题-C-A-3_比酒量

时间:2022-09-10 14:21:41
//第三届蓝桥杯软件类省赛真题-C-A-3_比酒量
/*
    有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,
	所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,
	又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经所剩无几,
	海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。

    等船长醒来,发现海盗船搁浅了。他在航海日志中写到:
	“......昨天,我正好喝了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”

    请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。

    如果有多个可能的答案,请列出所有答案,每个答案占一行。

    格式是:人数,人数,...

    例如,有一种可能是:20,5,4,2,0

    答案写在“解答.txt”中,不要写在这里!

*/

/*【解题思路】
解法:暴力枚举与深度优先搜索结合 
答案:
12 6 4 2 0
15 10 3 2 0
18 9 3 2 0
20 5 4 2 0
*/

#include<iostream>
#include<cstring>
using namespace std;

int drunkMan[5];//此数组用于表示每轮倒下的人,drunkMan[1]表示第1瓶酒喝完后,此时倒下的人 
bool visit[21];//此数组为一个标记访问数组 
int sum;//此变量用于表示船上一开始有多少人 

/*
 * @简介:深度优先搜索 
 * @参数:n表示第n轮,remainder表示第n轮后剩下的人 
 * @返回:无 
*/ 
void dfs(int n,int remainder)
{
	if(n==5)
	{
		//满足题目条件则输出:
		//所有倒下的人刚好等于刚开始的总人数,船长喝的酒刚好是一瓶 
		if(sum == (drunkMan[1] + drunkMan[2] + drunkMan[3] + drunkMan[4]) 
			&& (1.0/sum+1.0/(sum-drunkMan[1])+1.0/(sum-drunkMan[1]-drunkMan[2])+1.0/(sum-drunkMan[1]-drunkMan[2]-drunkMan[3])) == 1.0)
		{
			//输出刚开始的总人数 
			cout<<sum<<" ";
			int sum_d = 0;
			//输出之后每轮剩下的人 
			for(int i=1;i<=4;i++)
			{
				sum_d += drunkMan[i];
				cout<<sum-sum_d<<" ";
			}	
			cout<<endl;
		}
		return;
	}
	memset(visit,false,sizeof(visit));//注意在每轮枚举深搜前都需要初始化一次
	for(int i=1;i <= remainder;i++)
	{
		if(!visit[i])
		{
			visit[i] = true;
			drunkMan[n] = i;
			dfs(n+1,remainder-drunkMan[n]);
			visit[i] = false;
		}
	}
	return;
}

int main()
{
	memset(visit,false,sizeof(visit));
	for(sum = 1;sum<=20;sum++)
	{
		dfs(1,sum);
	}
	return 0;
}

/*
//分析:只需要判断出每次喝酒前有多少人即可,因为船长是最后一个倒下的,而且喝了正好一瓶,所以
//1/i+1/j+1/k+1/l=1,避免除法中的整型两个整型相除,结果自动转化为整数,
//故将其变成乘法后为:j*k*l+i*k*l+i*j*l+i*j*k==i*j*k*l 
#include <stdio.h>  
int main()  
{  
    int i,j,k,l,m;  
    for(i=4;i<=20;i++)  
    {  
        for(j=1;j<i;j++)  
        {  
            for(k=1;k<j;k++)  
            {  
                for(l=1;l<k;l++)  
                {  
                    if(j*k*l+i*k*l+i*j*l+i*j*k==i*j*k*l)  
                        printf("%d %d %d %d 0\n",i,j,k,l);  
                }  
            }  
        }  
    }     
    return 0;  
}  
*/