今天做新生赛,发现自己还是个菜狗.
题目描述
Jack是个吃鸡玩家,一个偶然的机会Jack来到了神秘的P城,Jack发现P城有 N 种宝物,每种宝物有 x[i] 个。但是当Jack想把他们全部拿走时,Jack发现由于背包限制,Jack现在只能带 3 件宝物回去,且每种宝物Jack最多只能带走 1 件。那么Jack一共有多少种带走 3 种不同宝物的方法?
输入
输入题目有多组测试数据
每组数据第一行输入一个m,代表m种类型(3<=m<=2000)
第二行有m个数,表述xi
样例输入
1 2 3
样例输出
6
这个题题意就是有N种物品,同种物品之间也各不相同.问从中存三个的方法数.
这个题暴力的话肯定过不了.
那举个几个例子分析下
如果 N = 4 ,四个值是1 2 3 4,即他们的值与他们的下标相同.
现在来写情况数 (1,2,3),(1,2,4),(1,3,4),(2,3,4);
一共有四种情况,排列上面数对的方式是我们先确定一个值i,然后循环这个值后面的值j,这样就确定了两个数,同理,按照上面的方式确定第三个数.
通过观察上述方式,其实就是第三次循环的时候,将所有j之后的所有数与a[i]a[j] (j后的所有数).这样的话我们就维护一个前缀和,每次到这遍历就可以简化一次循环.
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[1010];
bool cmp(int a,int b)
{
return a > b;
}
int main()
{
int n;
int T;
cin >> T;
while(T--)
{
cin >> n;
if(n == 1)
{
int temp;
cin >> temp;
cout << '0' << endl;
continue;
}
for(int i = 0;i <= n - 1; ++i)
{
cin >> a[i];
}
sort(a,a+n,cmp);
int t = 0;
for(int i = 0; ; ++i)
{
if(a[i] <= t)
{
cout << t << endl;
break;
}
t++;
}
}
return 0;
}