我只是来打个电话

题目

精神病院有一个这样的测试。
给出一个正整数集合,集合中的数各不相同,然后要求病人回答:
其中有多少个数,恰好等于集合中另外两个(不同的)数之和?
回答正确的人,即可以出院。
但是,条件是苛刻的——
一秒。
直到变成废墟前,也没有人从中逃出。
但是如今不同了。
对吧?
Input
共两行,第一行包含一个整数 n,表示测试题中给出的正整数个数。
第二行有 n 个正整数,每两个正整数之间用一个空格隔开,表示测试题中给出的正整数。
Output
一个整数,表示测验题答案。
Examples
telephone.in telephone.out
4
1 2 3 4
2
Notes
对于所有数据,满足 3 ≤ n ≤ 5000,给出的正整数不超过 10000。
Task1[50%]
n ≤ 100
Task2[100%]
无特殊限制


思路

暴力枚举,找出解,但超了时间。


 

代码(伪)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=1;i<n-2;i++)
        for(int j=i+1;j<=n-1;j++)
            for(int k=j+1;k<=n;k++)
                if(a[i]+a[j]==a[k])
                    sum++;
    cout<<sum<<endl;
    return 0;
}

思路(正解)

题意转化:对于给出的数列,有多少数可表示为另两数的和。

先排个序,桶排思路。以一个数组储蓄所有出现的和。最后循环判断是否b[i]>0。


代码

#include<bits/stdc++.h>
using namespace std;
int n,sum,a[100001],b[100001];
bool cmp(int x,int y)
{
    return x<y;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<i;j++)
        b[a[i]+a[j]]++;
    }
    for(int i=3;i<=n;i++)
    if(b[i]>0)
    sum++;
    cout<<sum;
    return 0;
}

完结!耶!

原文地址:https://www.cnblogs.com/abcdhh/p/11182199.html