总数统计

【题目描述】

给出n个数,统计两两之和小于等于k的方案数之和。

【输入描述】
第一行一个数n,表示数字的个数;
第二行到第n + 1行,每行一个不超过2,000,000,000的数k;
第n+2行一个数m,表示m个问题;
第n+3行到第n+m+2行,每行一个数m,询问表示n中两两组合不超过m的组合的个数。
【输出描述】

输出m行,每行对应一个答案。

【样例输入】

3

1

2

3

2

2

3

【样例输出】

0

1

【数据范围及提示】

30%的数据1 ≤ n ≤ 100, 1 ≤ m ≤ 50, k ≤ 2000;
100%的数据 1 ≤ n ≤ 10000, 1 ≤ m ≤ 100, k ≤ 2,000,000,000。

源代码:

#include<cstdio>
#include<algorithm> //第一次用sort。
using namespace std;
long long m,n,i[10001]; //不开Long Long会死人的!
void x2(long long t)
{
    int left=1,right=n,num(0),ans(0);
    while (left<=right) //二分查找最大的i[]。
    {
        int mid=(left+right)/2;
        if (i[mid]<=t)
        {
            left=mid+1;
            num=mid;
        }
        else
          right=mid-1;
    }
    for (int a=1;a<=num;a++)
    {
        int k(0);
        left=1;
        right=a-1;
        while (left<=right) //二分查找能够与i[a]匹配的最大的i[]。
        {
            int mid=(left+right)/2;
            if (i[mid]+i[a]<=t)
            {
                left=mid+1;
                k=mid;
            }
            else
              right=mid-1;
        }
        ans+=k; //此节点前面的节点自然都符合条件,累加。
    }
    printf("%d\n",ans);
}
int main() //二分法。
{
    scanf("%d",&n);
    for (int a=1;a<=n;a++)
      scanf("%d",&i[a]);
    sort(i+1,i+n+1); //升序排列。
    scanf("%d",&m);
    for (int a=1;a<=m;a++)
    {
        long long t; //恶心的Long Long。
        scanf("%d",&t);
        x2(t);
    }
    return 0;
}
posted @ 2016-06-05 08:13  前前前世。  阅读(283)  评论(0编辑  收藏  举报