幸运的袋子-牛客

题目:

一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3
你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得的多少种不同的幸运的袋子。

输入描述:
第一行输入一个正整数n(n ≤ 1000)
第二行为n个数正整数xi(xi ≤ 1000)

输出描述:
输出可以产生的幸运的袋子数
示例1
输入
3
1 1 1
输出
2

分析:

如果两数相加小于两数相乘,那么这两数中就必定有一个是1。
如果几个数的和小于他们的积,那么要想让它做到满足题设,能加进去的数只有1,
1可以让它的和增加1,但是积是不会变的。
如果我们将输入的数进行排序,那么依次取数尝试时,当条件一旦不满足时(连续的1必定满足条件),继续向后取数,取到的必定是大于1的,所以就可结束取数了
第一次取数时取到的必定是1,因为无论如何这一串数中都得有一个1,但一个数肯定不满足条件,所以只有一个数时也不满足条件

代码:

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

//幸运的袋子

int Check(vector<int> arr, int n, int tmp, int sum, int mul)
{
	int count = 0;
	int i = tmp;//初始位置
	
	for (; i < n; i++)
	{

		//先加和、乘积,用于后面判断
		sum += arr[i];
		mul *= arr[i];
		
		if (i == 0 && sum == arr[0]) //只有一个元素时,不可能满足条件
			Check(arr, n, i + 1, sum, mul);

		else
		{
			if (sum > mul)//和大于积时,满足条件
			{
				count += 1 + Check(arr, n, i + 1, sum, mul);//递归,判断后续的数是否可以继续组成满足条件的组合
			}

			else
				break;//如果不满足条件,那么后面的数必定不符合条件

			sum -= arr[i];//去除当前数,继续尝试后面的数
			mul /= arr[i];

			//相同号码无区别,就意味着,第一个1号球和第二个1号球是没有区别的,
			//那么在单独使用过第一个1号球后,就不可以再单独使用第二个1号球了,
			//多个同号组合可以正常进行
			while (i < n - 1 && arr[i] == arr[i + 1])
				i++;
		}

	}

	return count;
}

int main()
{
	int n = 0;
	while (cin >> n)
	{

		vector<int> arr(n);
		for (auto& a : arr)
			cin >> a;

		sort(arr.begin(), arr.end());//对输入的小球进行升序排序

		cout << Check(arr, n, 0, 0, 1) << endl;//(n为元素个数,0为当前位置,0为加和初值,1为乘积mul初始值)

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Mmonster23/article/details/106846957