題目鏈接 :地址
紫書 p237 8-3
題意 : T組樣例 有abcd四個集合 每個集合有n個數 求從每一個集合中挑出一個數,這四個數的和爲0的組合個數
兩種方法,目前只寫了一種(Hash 法,這種方法第一次用,學習一下)
參考博客 :https://blog.csdn.net/hjt_fathomless/article/details/51361652
Hash 塊
struct Hash_map
{
static const int mask=0x7fffff;
int q[mask+1];
int p[mask+1];
void clear_()
{
memset(q,0,sizeof(q));
}
int& operator [](int x)
{
int i;
for(i=x&mask;q[i]&&p[i]!=x;i=(i+1)&mask);
p[i]=x;
return q[i];
}
}Hash;
第一次重載 [ ] 號,挺好的
全部代碼
#include <bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
#define ll long long
#define inf 0x3f3f3f3f
void intt()
{freopen("in","r",stdin);}
struct Hash_map
{
static const int mask=0x7fffff;
int q[mask+1];
int p[mask+1];
void clear_()
{
memset(q,0,sizeof(q));
}
int& operator [](int x)
{
int i;
for(i=x&mask;q[i]&&p[i]!=x;i=(i+1)&mask);
p[i]=x;
return q[i];
}
}Hash;
int main()
{
// intt();
int t;
cin>>t;
while(t--)
{
int a[4003];
int b[4003];
int c[4003];
int d[4003];
int n;
cin>>n;
Hash.clear_();
for(int i=0;i<n;i++)
cin>>a[i]>>b[i]>>c[i]>>d[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
Hash[a[i]+b[j]]++;
}
}
ll sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
sum+=Hash[-c[i]-d[j]];
// cout<<Hash[-c[i]-d[j]];
}
}
cout<<sum<<endl;
if(t)
cout<<endl;
}
return 0;
}
挺實用的方法,感覺比二分好寫
二分思路 : 把所有的A+B存起來,排個序,然後用 lower_bound來找和 c[i]+d[j]相反數所在位置 統計個數