Values whose Sum is 0(四列数和为零问题(二分基础))

题目来源:[NWPU][2014][TRN][5]二分和贪心A题

http://vjudge.net/contest/view.action?cid=49586#problem/A

作者:npufz

问题:给定四列数,共有N行,(N<4000),求算出在任意一列里面挑选出一个数字,使四个数字的和为零的情况有多少种,每个数字的大小不超过2的28次方。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
long int b[16000000],c[16000000];
int main()
{
    int n;
    long int a[4000][4],cnt,i,j,num1,num2;
    long long int sum;
    scanf("%d",&n);
    for(i=0; i<n; i++)
        scanf("%ld%ld%ld%ld",&a[i][0],&a[i][1],&a[i][2],&a[i][3]);
    cnt=0;
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
        {
            b[cnt]=(0-a[i][0]-a[j][1]);
            cnt++;
        }
    cnt=0;
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
        {
            c[cnt]=a[i][2]+a[j][3];
            cnt++;
        }
    sort(c,c+cnt);
    sum=0;
    for(i=0; i<cnt; i++)
    {
        num1=(lower_bound(c,c+cnt,b[i])-c);
        num2=(upper_bound(c,c+cnt,b[i])-c);
        if(c[num1]==b[i])
        {
            sum+=(num2-num1);
        }
    }
    cout<<sum<<endl;
    return 0;
}

反思:一开始的时候觉得枚举能过,就试图用有限制条件的枚举,就是先求算前两列的和,再求算后两列的和,然后对两列和分别进行升降序排列,然后就控制两列和的加法顺序,只对能够是和为零的情况进行遍历,就果断超时了,可见和为测试数据和为零的情况特别的多,然后改用二分,结果对c++标准库的UPPER_BOUND和LOWER_BOUND不够熟悉,没有理解它是知道那个元素的插入位置,就WA了,经过对找到元素是不是进行判断后,就又超时了,可能是CIN比SCANF费时间,就改为SCANF,同时去掉一个排列,只对一列和进行排列,就又WA了,经大神指点,原来排序和查找时漏掉了最后一个元素

教训:SCANF更省时,UPPER_BOUND和LOWER_BOUND只是找到插入的位置,和那个元素在集合中存不存在没有关系,对集合排序和查找不能漏掉任何元素


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值