题目描述
给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列 , 这个问题的答案就是 , 因为 。
输入格式
共两行,第一行是数列中数的个数 ( ),第二行是由 个不大于 的正整数组成的数列,相邻两个整数之间用单个空格隔开。
输出格式
一个整数,即数列中等于其他两个数之和的数的个数。
样例
样例输入
4
1 2 3 4
样例输出
2
你题目的解答代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
int a[105];
int main() {
int n, ans = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++){
bool f = false;
for(int j = 0; j < n; j++){
for(int k = 0; k < n; k++){
if(i != j && i != k && j != k && a[i] == a[j] + a[k]){
f = true;
}
}
}
if(f == true)
ans++;
}
cout << ans;
return 0;
}
如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!
故代码为
#include <bits/stdc++.h>
using namespace std;
int v[10010];int a[110];
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
v[a[i]]++;
}
int ans=0;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(a[i]+a[j]<=10000 && v[a[i]+a[j]]){ //第一个条件是为了防止数组越界
ans++;
v[a[i]+a[j]]--;
}
printf("%d",ans);
return 0;
}
您想问的应该是https://www.luogu.com.cn/problem/P2141吧。
根据这道题的复杂度,使用 O(n^3) 的算法足以通过此题。
于是我们枚举 i,j,k,若 a[i]+a[j]=a[k],则将答案累加1.
得出 AC 代码:
#include<bits/stdc++.h>
using namespace std;
int n,ans;
int a[110],vis[110];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(a[k]==a[i]+a[j]&&!vis[k]){//相同的k有可能被重复计数,所以增加vis数组维护
ans++;
vis[k]=1;
}
}
}
}
cout<<ans<<endl;
return 0;
}
但显然还是可以优化的。
注意到本题的特性,即所有数的大小不超过 10000,也就是说,我们可以开一个桶,来记录数列中每个数出现的次数。
然后只需要枚举 i,j 来判断 a[i]+a[j] 在数列里是否又出现,若出现则将答案累加一即可。
若出现了之后,a[i]+a[j] 在桶里记录的出现的次数要减一,因为相同的数不能累加多次。
于是得出时间复杂度 O(n^2) 代码:
#include<bits/stdc++.h>
using namespace std;
int n,ans;
int a[110],vis[10001];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
vis[a[i]]++;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(vis[a[i]+a[j]]){
ans++;
vis[k]--;
}
}
cout<<ans<<endl;
return 0;
}
望采纳