题目
题目描述
给出一个整数的集合 ,求有多少组 , , 满足 。
输入格式
第1行:1个整数N (1 ≤ N ≤ 100),表示元素的个数
按下来N行,每行一个整数,数的大小在-30000 ~ 30000之间,数值均不相同
输出格式
第1行:1个整数,表示满足条件的6个数的组数。
样例
样例组数 | 样例输入 | 样例输出 |
---|---|---|
1 | 1 1 | 1 |
2 | 2 2 3 | 4 |
3 | 2 -1 1 | 24 |
4 | 3 5 7 10 | 10 |
分析
把方程变下形得:
,很明显的折半搜索。
把每一组
存入哈希表,枚举
,在哈希表中查找
的个数,累加起来即可。
极其恶心的是:
- 只能用
vector
!只能用vector
!只能用vector
! 我用set
直接爆掉40分…… - ! ! !我没判断又爆掉10分……
于是这道最水的题我只得了50分。
代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define MOD 100003
#define MAXN 100
int N;
int S[MAXN+5];
long long Ans;//开long long是正常人看到方案统计题后的必然想法
vector<pair<long long,int> > A[MOD+5];//pair中存值和出现次数(其实不开long long亦可)
//vector的哈希操作不想说了
int Hash(long long key){
return (key%MOD+MOD)%MOD;
}
void HashInsert(long long key){
int pos=Hash(key);
for(int i=0;i<int(A[pos].size());i++)
if(A[pos][i].first==key){
A[pos][i].second++;
return;
}
A[pos].push_back(make_pair(key,1));
}
int HashFind(long long key){
int pos=Hash(key);
for(int i=0;i<int(A[pos].size());i++)
if(A[pos][i].first==key)
return A[pos][i].second;
return 0;
}
int main(){
freopen("solution.in", "r" ,stdin);
freopen("solution.out","w",stdout);
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d",&S[i]);
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
for(int k=1;k<=N;k++)
HashInsert(S[i]*1ll*S[j]+S[k]);
for(int i=1;i<=N;i++)
if(S[i])//注意!注意!注意!
for(int j=1;j<=N;j++)
for(int k=1;k<=N;k++){
long long tmp=S[i]*1ll*(S[j]+S[k]);
Ans+=HashFind(tmp);
}
printf("%I64d",Ans);
}