标签:des style blog http io color ar os java
1 3 1 1 2 1 2 2 1 1
5
题目大意:
给定一些集合,选择两个来自不同集合的数,加和大于k,问有多少种选择方案。
解题思路:
答案=从所有数中选择的两个加和大于k的数的方案数-在同一个集合中选择的两个加和大于k的数的方案数
而对于同一个集合中选择的两个加和大于k的方案数是可以直接排序然后利用单调性快速统计出来的。
//546MS 1860K
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
long long s[1007][107],num[1007],array[100007];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
long long k,a=0,ans=0;
scanf("%d%I64d",&n,&k);
for(int i=0; i<n; i++)
{
scanf("%I64d",&num[i]);
for(int j=0; j<num[i]; j++)
{
scanf("%I64d",&s[i][j]);
array[a++]=s[i][j];
}
sort(s[i],s[i]+num[i]);
}
sort(array,array+a);
int x=a-1;
for(int i=0; i<a; i++)//从所有数中选择的两个加和大于k的数的方案数
{
while(array[i]+array[x]>k&&x>i)x--;
if(i>x)ans+=(a-i-1);
else ans+=(a-x-1);
}
long long count=0;
for(int i=0; i<n; i++)//在同一个集合中选择的两个加和大于k的数的方案数
{
int x=num[i]-1;
for(int j=0; j<num[i]; j++)
{
while(s[i][j]+s[i][x]>k&&x>j) x--;
if(j>=x)count+=(num[i]-j-1);
else count+=(num[i]-x-1);
}
}
printf("%I64d\n",ans-count);
}
}
标签:des style blog http io color ar os java
原文地址:http://blog.csdn.net/crescent__moon/article/details/40985923