1. 程式人生 > >hihocode 1505 : 小Hi和小Ho的禮物

hihocode 1505 : 小Hi和小Ho的禮物

描述

某人有N袋金幣,其中第i袋內金幣的數量是Ai。現在他決定選出2袋金幣送給小Hi,再選2袋金幣送給小Ho,同時使得小Hi和小Ho得到的金幣總數相等。他想知道一共有多少種不同的選擇方法。

具體來說,有多少種下標四元組(i, j, p, q)滿足i, j, p, q兩兩不同,並且i < j, p < q, Ai + Aj = Ap + Aq。

例如對於陣列A=[1, 1, 2, 2, 2],一共有12種選法:

i j p q
1 3 2 4
1 3 2 5
1 4 2 3
1 4 2 5
1 5 2 3
1 5 2 4
2 3 1 4
2 3 1 5
2 4 1 3
2 4 1 5
2 5 1 3
2 5 1 4

輸入

第一行包含一個整數N。

第二行包含N個整數,A1, A2, A3 … AN。

對於70%的資料,1 <= N <= 100

對於100%的資料,1 <= N <= 1000, 1 <= Ai <= 1000000
輸出

不同選擇的數目。
樣例輸入

5  
1 1 2 2 2

樣例輸出

12

如果不考慮非法組合的話, 辣麼 對於 a[i] + a[j] = a[q] + a[p] = M。 假如 有x 對 a[i] + a[j] = M 的話,答案就是 C(m,2).
考慮重複。 舉個栗子, 對於序列, 1 1 2 2 2。 當你M = 3,選擇(1,3)(下標)時,你再選擇其他(a[q],a[p])的情況,你要去掉 下標(1,4,)(1,5)(3,2)。 也就是 包含(1,3)中某一個的情況。可以發現有 (n+m-2)n為1個數,m為3個數。

#include <iostream>
#include <cstring>
#include <map>
using namespace std;

const int maxn = 1e5+50;
#define FCIN  ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
const int MAXINT = 0x7fffffff;
const int MININT = 0x80000000;
typedef long long LL;

int a[maxn]; 
int cou[10*maxn];
map<int,int
>
M; int main(int argc, char* argv[] ){ FCIN; int n; cin>>n; M.clear(); memset(cou,0,sizeof(cou)); for(int i=1;i<=n;i++) cin>>a[i],cou[a[i]]++; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ M[ a[i]+ a[j] ]++; } } LL ans = 0; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ if(a[i] != a[j]){ ans += M[ a[i] + a[j] ] - (cou[a[i]] + cou[a[j]] -2) -1 ; } else{ ans += M[ a[i] + a[j] ] - (cou[a[i]] + cou[a[j]] -4) - 1; } } } cout<<ans<<endl; return 0; }