|
a + b = c | ||||||
| ||||||
|
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);
}
}
探讨使用双向指针优化算法解决a+b=c问题的方法,通过遍历与比较实现高效匹配。
420

被折叠的 条评论
为什么被折叠?



