题意:
多多有一个智商值K。
有n个班级,第i个班级有mi个人。智商分别是v1,v2,.....vm。
多多要从这些人中选出两人。要求两人智商和大于K,并且两人不同班。问总共有多少种方案。
解法:
先排序每个班的 然后总的排序 第一个同学用枚举的方法 第二个同学用二分
ans就等于总的可能情况减去每个班的可能情况。
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5101
代码:
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
#define INF 0x0f0f0f0f
using namespace std;
int a[100005],x[1005][105];
int erfen(int *a,int l,int n,int q)
{
int mid,r=n;
if(q>=a[n]) return 0;
while(l<r)
{
mid=(l+r)/2;
if(a[mid]<=q) l=mid+1;
else r=mid;
}
return n-l+1;
}
int main()
{
int T;
int n,k,l,m,i,j,cnt;
long long ans;
scanf("%d",&T);
while(T--)
{
cnt=1;
ans=0;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&k);
x[i][0]=k;
for(j=1;j<=k;j++)
{
scanf("%d",&x[i][j]);
a[cnt++]=x[i][j];
}
sort(x[i]+1,x[i]+1+k);
}
sort(a+1,a+cnt);
cnt--;
for(i=1;i<=cnt;i++)
{
ans+=erfen(a,i+1,cnt,m-a[i]);
}
for(i=0;i<n;i++)
{
for(j=1;j<=x[i][0];j++)
{
ans-=erfen(x[i],j+1,x[i][0],m-x[i][j]);
}
}
printf("%I64d\n",ans);
}
return 0;
}