线上OJ:
核心思想:
1、题目所求为"有多少个数=其他两个数之和 ",故不管5是由1+4组成,还是2+3组成,都只算一次。
2、利用 set 有 自动去重 的功能,只要将结果丢进set,最后输出set的size即可
3、由于题目的 n 只有100,非常小,所以可以用三重循环暴力枚举直接完成
cpp
#include <bits/stdc++.h>
#define MAXN 105
using namespace std;
set<int> s; // 利用set有自动去重的功能,只要将结果丢进set,最后输出set的size即可
int n;
int a[MAXN];
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
for(int k = 1; k <= n; k ++)
{
if(a[i]+a[j]==a[k])
{
s.insert(a[k]);
}
}
cout << s.size() << endl;
return 0;
}
思考:
如果 n 的范围超过 1 0 3 10^3 103,则上述方法会超时,这是可以考虑反向枚举答案 ,因为a[i]不超过10,000,所以最终的和不超过20000。只要 建20000个桶,最后看哪些桶的结果被标记过了即可
cpp
#include <bits/stdc++.h>
#define MAXN 105
using namespace std;
int n, ans = 0;
int a[MAXN];
int res[20005] = {0};
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
res[a[i] + a[j]] = 1; // 标记为计算过
for(int i = 1; i <= n; i++)
if(res[ a[i] ]) ans++; // 如果a[i]数组中的值在res[i]被标记过,则ans++
cout << ans << endl;
return 0;
}