hrbust 1710 a+b=c【双向指针】

来源:互联网 发布:rbac权限管理表mysql 编辑:程序博客网 时间:2024/06/10 11:40

a + b = c

Time Limit: 2000 MS

Memory Limit: 65536 K

 

Total Submit: 248(79 users)

Total Accepted: 76(61 users)

Rating: 

Special Judge: No

 

Description

有A、 B、 C 三个集合的,其中a∈A, b ∈ B, c ∈ C,求有多少种方式使得a + b = c。

Input

有多组测试数据,请处理到文件结束。

对于每组测试数据,有三行:

第一行为A集合的描述,第一个数为n,表示A集合有n个数,接下来有n个整数a1~an。

第二行为B集合,第三行为C集合,表示含义参考第一行。

每个集合中的数两两不相等。

1<=n<=5000,|ai| <= 1 000 000 000

Output

对于每组测试数据,输出一行,包含一个整数,表示有多少种组合方式。

Sample Input

3 -10 4 -6

3 -10 3 -1

3 3 -4 -6

3 -8 -9 -4

3 9 -10 2

3 -8 -7 5

3 -4 -6 -2

3 9 -9 -2

3 3 -13 -4

Sample Output

2

2

3

 

分析:每个集合都是最大5000的数据量,如果暴力,当然是不可能AC的一种方案,5000*5000*5000是个很大的操作量,1000ms的小身板还是禁不住这样的狂风骤雨的,所以嘞,我们需要优化,最直接简单的能够想到a+b的值在c【】中二分查找,这样就能优化到5000*5000*log(5000),但是好像这样就交了好像有点在赌后台数据的感觉,不过也还是敲了一发,实力TLE,所以呢,还是需要优化。


思路:这个思路是从学长门辣里学到的,我队长告诉我这东西可以简称为双向指针,那么我们就叫双向指针吧,我们对a【】,b【】进行排序,然后呢,我们遍历c数组,然后再用两个指针遍历a,b数组,一个定位在a数组的开头,一个定位在b数组的结尾,a向右遍历,b向左遍历,如果a【pa】+b【pb】==c,辣么我们就找到了一种方案,并且让pa++,pb--;如果a【pa】+b【pb】<c呢?因为我们的pa是从左到右遍历的,是让值变大的方式,所以我们pa++,相反,pb--。


AC代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int a[5005];int b[5005];int c[5005];int conta,contb,contc;int main(){    while(~scanf("%d",&conta))    {        for(int i=0;i<conta;i++)scanf("%d",&a[i]);        scanf("%d",&contb);for(int i=0;i<contb;i++)scanf("%d",&b[i]);        scanf("%d",&contc);for(int i=0;i<contc;i++)scanf("%d",&c[i]);        sort(a,a+conta);        sort(b,b+contb);        sort(c,c+contc);        int output=0;        for(int i=0;i<contc;i++)        {            int A=0;int B=contb-1;            while(A<conta&&B>=0)            {                int tmp=a[A]+b[B];                if(tmp==c[i])                {                    output++;A++;B--;                }                else if(tmp>c[i])                {                    B--;                }                else A++;            }        }        printf("%d\n",output);    }}















0 0
原创粉丝点击