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

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);
    }
}















你可能感兴趣的:(1710,1710,哈理工oj,hrbust)