【题解】【模拟,枚举】—— [NOIP2014 普及组] 珠心算测验
[NOIP2014 普及组] 珠心算测验
题目背景
NOIP2014 普及 T1
题目描述
珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术。珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及。
某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法。他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?
最近老师出了一些测验题,请你帮忙求出答案。
输入格式
共两行,第一行包含一个整数 n n n,表示测试题中给出的正整数个数。
第二行有 n n n 个正整数,每两个正整数之间用一个空格隔开,表示测试题中给出的正整数。
输出格式
一个整数,表示测验题答案。
输入输出样例
输入 #1
4
1 2 3 4
输出 #1
2
提示
【样例说明】
由 1 + 2 = 3 , 1 + 3 = 4 1+2=3,1+3=4 1+2=3,1+3=4,故满足测试要求的答案为 2 2 2。
注意,加数和被加数必须是集合中的两个不同的数。
【数据说明】
对于 100 % 100\% 100% 的数据, 3 ≤ n ≤ 100 3 \leq n \leq 100 3≤n≤100,测验题给出的正整数大小不超过 10 , 000 10,000 10,000。
解法1.直接枚举
1.1.思路解析
首先将数组排序,可以省去很多不必要的麻烦。
直接枚举两个加数,计算出和,再遍历后面的数组,看看有没有这个值,有就把答案加 1 1 1。
注意:因为要求的是不同的和,所以我们还需要判重,详见代码。
1.2.AC代码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
int main()
{
int n,a[MAXN],i,j,k,num=0;
bool is_have[MAXN]={};//用一个数组记录和出现过没有
cin>>n;
for(i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);//排序
for(i=1;i<=n;i++)//枚举加数
for(j=i+1;j<=n;j++)//枚举被加数,保证不重复
for(k=j;k<=n;k++)//枚举和
if(a[i]+a[j]==a[k]&&is_have[k]==0)
{
num++;
is_have[k]=1;
}
cout<<num;
return 0;
}
扩展.二分查找优化
2.1.思路解析
在枚举和的时候,我们可以直接使用upper_bound
寻找,可以优化时间复杂度致
O
(
n
2
log
n
)
O(n^2\log n)
O(n2logn),相比
O
(
n
3
)
O(n^3)
O(n3)有很大进步。
2.2.AC代码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
int main()
{
int n,a[MAXN],i,j,k,num=0;
bool is_have[MAXN]={};//用一个数组记录和出现过没有
cin>>n;
for(i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);//排序
for(i=1;i<=n;i++)//枚举加数
for(j=i+1;j<=n;j++)//枚举被加数,保证不重复
{
int k=upper_bound(a+1,a+n+1,a[i]+a[j])-(a+1);//二分查找
if(a[i]+a[j]==a[k]&&is_have[k]==0)
{
num++;
is_have[k]=1;
}
}
cout<<num;
return 0;
}
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育