小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第一行包含乙個整數n。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個整數,a1, a2, a3 ... an。
對於70%的資料,1 <= n <= 100
對於100%的資料,1 <= n <= 1000, 1 <= ai
<= 1000000
不同選擇的數目。
樣例輸入
5樣例輸出1 1 2 2 2
12
對 i,j,p,q遍歷的話時間複雜度會達到o(n4),所以考慮優化p,q。建立sum值的次數雜湊與num出現次數的hash。
當固定了i,j時,可以求出當前的sum值,可以在剛剛建立的雜湊表裡找出當前sum值出現的次數,減去跟i,j重複值時的次數即為當前情況下的次數。
還是直接貼大神的思路
: 假設分配給小hi的金幣為a[i]
和a[j]
,現在的問題是求剩下的元素中有多少組p, q
使得a[i] + a[j] = a[p] + a[q]
。如果暴力列舉所有可能的p, q
,需要o(n^2)
時間,再加上列舉i, j
的時間,時間複雜度是o(n^4)
,會超時。所以不能列舉p, q
。
把輸入儲存在陣列a
中。
令sumcnt[x]
表示兩袋金幣之和a[i] + a[j] = x
組合數。
令cnt[y]
表示元素y
出現的次數。
假設分配給小hi的金幣為x = a[i] + a[j]
,那麼x
一共有sumcnt[x]
種可能的組合。
令c1 = cnt[a[i]], c2 = cnt[a[j]]
,
假設a[i] != a[j]
。
去掉a[i], a[j]
之前,a[i]
和a[j]
一共可以組成c1 * c2
個x
。去掉a[i]
後,還有c1 - 1
個與a[i]
相同的元素,去掉a[j]
後,還有c2 - 1
個與a[j]
相同的元素,它們還可以組成(c1 - 1) * (c2 - 1)
個x
。
所以,如果分配給小hi的金幣為a[i]
和a[j]
,那麼存在sumcnt - (c1 * c2 - (c1 - 1) * (c2 - 1))
對p, q
使得a[i] + a[j] = a[p] + a[q]
。
當a[i] == a[j]
時,也是類似的處理。
現在,求p, q
的組數隻需要o(1)
,總的時間複雜度是o(n^2)
。
**:#include
#include
#include
#include
#include
#include
using namespace std;
int num[1002];
int main()
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)else
}
}
cout<
注意有點奇怪的地方是,ans需為long long,否則答案錯誤。明明為int時,暴力還能過70%。
小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。...
小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。...
hihoCoder 1606 小Hi和小Ho的密碼
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小hi和小ho一直使用加密的方式傳輸訊息。他們使用如下方法來生成一組密碼 首先小hi和小ho選擇乙個整數 n pk 其中p質數 k是正整數,也即n是質數或質數的冪 其次,他們會求出兩個整數a和b滿足0 a b n,並且,n...