杀死恶龙第二季

王国里又双叒叕来了一头恶龙,国王要征集勇士去杀死这头恶龙。王国里一共有n个佣兵团,每个佣兵团里有ai名勇士,每名勇士的攻击力为vij,假定恶龙的生命力值为k。现在国王只想派不同的两个佣兵团里的两名勇士去完成这个任务,当两名勇士的攻击力之和大于等于k时,表明他们可以完成任务。统计一共多少种方案。

输入格式

第一行为正整数t(≤10),表示数据组数;每组数据中,第一行为正整数n(≤1000)k(≤109),接下来n行,每行第一个正整数ai(≤100),表示这个佣兵团的勇士个数,接下来ai个正整数vij(≤109)表示每名勇士的攻击力。

输出格式

对于每组数据,输出合理的方案数。

输入/输出例子1

输入:

1

3 1

1 2

1 2

2 1 1

输出:

5

解释在程序中:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1005, M=105;
int k, a[N], v[N][M], all[N*M];
int main(){
	int t, n;
	cin>>t;
	while (t--){
		cin>>n>>k;
		int tot=0;
		for (int i=0; i<n; i++){
			cin>>a[i];
			for (int j=0; j<a[i]; j++){
				cin>>v[i][j];//v[i]记录本组佣兵
				all[tot++]=v[i][j];//all记录所有佣兵 
			}
			sort(v[i], v[i]+a[i]);//本组佣兵 
		}
		sort(all, all+tot);//所有佣兵排序
		ll ans=0;
		for (int i=0; i<n; i++){
			for (int j=0; j<a[i]; j++){
				int pos;
//lower_bound(begin,end,num)返回指向大于等于num的第一个值的位置,使用二分查找的方法 
//upper_bound(begin,end,num) 返回指向大于num的第一个值的位置
				pos=lower_bound(all, all+tot, k-v[i][j])-all;
				ans+=tot-pos;//所有数中大于k-v[i][j]的
				pos=lower_bound(v[i], v[i]+a[i], k-v[i][j])-v[i];
				ans-=a[i]-pos;//减去第i个团里中大于k-v[i][j]的
			}
		}
		cout<<ans/2<<endl;//重复计算,所以除以2 
	}
	return 0;
}
/*
把每个佣兵团勇士的攻击力排序,再把所有勇士的攻击力合起来排序,
枚举第i个佣兵团的第j个勇士,其攻击力为v[i][j],要想找到一个满
足条件的勇士,其攻击力需大于k-v[i][j],先从所有勇士中二分搜索得
到第一个攻击力大于k-v[i][j]的勇士,那么这个勇士和后面的勇士都满足条件,
但是要去掉同一个佣兵团的勇士,再在v[i]中二分搜索找到第一个攻击力大于
k-v[i][j]的勇士,减掉即可
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值