首页 > 学院 > 开发设计 > 正文

POJ2785-Values whose Sum is 0

2019-11-06 06:54:32
字体:
来源:转载
供稿:网友

题目描述: 题目链接:http://poj.org/PRoblem?id=2785 这个题的意思是给你四个具有相同元素个数的集合,问能否从每个集合里面挑出一个数,使得四个数的和为0,输出一共有多少种组合可以实现。 题目分析 : 这是第二周训练第二场的一个题,从前做过这个题,可惜当时没有想起来怎么做,总是超时==;这个题可以求出前两个集合的所有和的情况存到一个数组里面,然后对这个数组进行排序。然后再用后两个集合求和,每求出一个和就用lower_bound()upper_bound 函数在数组中寻找。这道题考的就是这两个函数的用法,可惜我没有想起来怎么用TAT。 复习一下两个函数用法:

ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于值val的位置。比如在本题中大概可以这么用:int pos1=lower_bound(sum1,sum1+k,-cnt)-sum1; int pos2=upper_bound(sum1,sum1+k,-cnt)-sum1; if(sum1[pos1]==-cnt) sum+=(pos2-pos1); 因为函数使用的是二分查找,所以速度较快,但是要确保已经对数组进行过排序。

此函数详细用法见这篇博文:http://blog.csdn.net/u013475704/article/details/46458723

给出代码:

#include <iostream>#include <algorithm>#include <iomanip>#include <map>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>using namespace std;int num[11];int sum1[16000010];int main(){ int n; while(scanf("%d",&n)!=EOF) { int num1[4010],num2[4010],num3[4010],num4[4010]; for(int i=0;i<n;i++) { scanf("%d%d%d%d",&num1[i],&num2[i],&num3[i],&num4[i]); } //int sum1[16000000]; int k=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) sum1[k++]=num1[i]+num2[j]; sort(sum1,sum1+k); int sum=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { int cnt=num3[i]+num4[j]; int pos1=lower_bound(sum1,sum1+k,-cnt)-sum1; int pos2=upper_bound(sum1,sum1+k,-cnt)-sum1; if(sum1[pos1]==-cnt) sum+=(pos2-pos1); } cout<<sum<<endl; } return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表