题目描述
已知集训队现有8个队,每队有一个能力值,且不同队能力值不同,这次友谊赛需要派出4个队,剩余4个队则参加集训队队内的比赛。为了成绩不至于太差,我校教练决定派出的4支队能力值之和要大于剩下的四支队,那请问有多少种选派方法?
输入
数据的第一行为组数T,以下有T组数据,每组数据由8个数组成,分别为a1,a2,……a8(1<=ai<=100000,1<=i<=8),表示每个队的能力值,并且8个数两两不同。
输出
对于每组数据,输出满足条件的方案数
样例输入
1
1 2 3 4 5 6 7 8
样例输出
31
代码
#include <bits/stdc++.h>
using namespace std;
int n;
int sz[50];//存输入的数
int a[50];//存每一次选的数
int sum_all;//输入的所有数之和
int cnt;//派遣方案总数
void judge() { //判断函数
int sum_choose = 0; //被选中的数字之和
int sum_left = 0; //未选中的数字之和
for (int i = 1; i <= 4; i++) {
sum_choose += a[i];
}
sum_left = sum_all - sum_choose;
if (sum_choose > sum_left) cnt++;//选中数字之和大于未选中数字之和,计数增一
}
void search(int t) { //搜索函数,t始终指向下一个
/*递归的出口*/
if(t > 4) { //搜完了
judge(); //对找到的数字进行判断
return;
}
/*递归的主体*/
for(int i = 1; i <= 8; i++) { //枚举每一个数
if(sz[i] > a[t - 1]) { //当sz[i]大于a数组的最后一个数(这样能避免重复)
a[t] = sz[i]; //将sz[i]存入a数组
search(t + 1);//继续搜索
a[t] = 0; //回溯
}
}
}
int main(){
cin>>n;
while (n--) {
cnt = 0;
sum_all = 0;
for (int i = 1; i <= 8; i++) {
cin>>sz[i];
sum_all += sz[i]; //所有队伍的能力总和
}
sort(sz, sz+8); //为了方便之后的搜索,这里排它一下
search(1); //深搜
cout<<cnt<<endl;
}
return 0;
}
小结
这道题让我想起了组合数的输出,也就是给你n个数字,输出m(m<n)个数字的所有组合,其实这两道题都是一样的解决方案,都是用dfs搜索,不过这道题要将所选数字和与剩余数字和作比较,大的话计数增一即可。