UVA_11524
题意
给出A B C D四个集合,要求从每个集合中选择a b c d使得a+b+c+d=0。
问有多少种选择方法?
解决
可以使用HASH来做,我还不会/(ㄒoㄒ)/~~
参考下别人的博客,这个方法很妙^_^
1. 意识到O(n^4)的算法会超时
2. 通过枚举a+b的所有可能,查找-c-d的个数,累加即可
3. 注意数组比较大,开在全局里面
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=4005;
int a[maxn],b[maxn],c[maxn],d[maxn],sum[maxn*maxn]; //数组比较大,不开全局会存不下
int main()
{
int cases;
scanf("%d",&cases);
while(cases--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
int cnt=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
sum[cnt++]=a[i]+b[j]; //枚举a+b
}
}
sort(sum,sum+cnt);
long long ans=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
ans+=upper_bound(sum,sum+cnt,-c[i]-d[j])-lower_bound(sum,sum+cnt,-c[i]-d[j]);
//upper返回第一个严格大于它的值,lower返回的是第一个大于等于它的值,相减就是这个值出现的次数
//妙哉妙哉!!!
}
}
cout<<ans<<endl;
}
}