PAT (Basic Level) Practice1030 完美数列

30 篇文章 0 订阅

1030 完美数列

一、题目

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M M M,最小值是 m,如果 M ≤ m p M≤mp Mmp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

二、输入输出

输入格式

输入第一行给出两个正整数 N 和 p,其中 N( ≤ 1 0 5 ≤10^5 105)是输入的正整数的个数,p( ≤ 1 0 9 ≤10^9 109​​)是给定的参数。第二行给出 N 个正整数,每个数不超过 10 ​ 9 10​^9 109​​ 。

输出格式

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

三、样例

输入样例

10 8
2 3 20 4 5 1 6 7 8 9

输出样例

8

四、题目分析

首先读入数据,对数据进行排序,依次遍历最小值,找到小于 m p mp mp的数量(即找到第一个大于 m p mp mp的数),输出其中的最大值。由于对数据已经进行排序,在进行查找第一个大于mp的数时,使用顺序查找会超时,因此需要采用二分查找,使用函数lower_bound()upper_bound()。还需要主要数据类型,使用int会溢出。

五、代码

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	long long int p;
	int num_max=0;
	cin>>n>>p;
	vector<long long int> v;
	for(int i=0;i<n;i++){
		long long int x;
		cin>>x;
		v.push_back(x);
	}
	sort(v.begin(),v.end());
	for(int i=0;i<v.size();i++){
		long long int x=v[i]*p;
		int num=upper_bound(v.begin()+i,v.end(),x)-(v.begin()+i);
		if (num>num_max)
			num_max=num;
	}
	cout<<num_max;
}

六、总结

1.数据类型的存储范围

  • 整型数据存储空间及数值范围(Visual C++)

    类型名称字节数数值范围数值范围(二进制)大致范围(十进制)
    [signed] int有符号基本整型4[-2,147,483,648 ~ 2,147,483,647] − 2 31 -2^{31} 231~ ( 2 31 − 1 ) (2^{31}-1) (2311) − 1 0 9 -10^{9} 109~ 1 0 9 10^{9} 109
    unsigned int无符号基本整型4[0 ~ 4,294,967,295]0 ~ ( 2 32 − 1 ) (2^{32}-1) (2321) 0 0 0~ 1 0 9 10^{9} 109
    [signed] short [int]有符号短整型2[-32,768 ~ 32,767] − 2 15 -2^{15} 215~ ( 2 15 − 1 ) (2^{15}-1) (2151) − 1 0 5 -10^{5} 105~ 1 0 5 10^{5} 105
    unsigned short [int]无符号短整型2[0 ~ 65,535]0 ~ ( 2 16 − 1 ) (2^{16}-1) (2161)0 ~ 1 0 5 10^{5} 105
    [signed] long [int]有符号长整型4[-2,147,483,648 ~ 2,147,483,647] − 2 31 -2^{31} 231~ ( 2 31 − 1 ) (2^{31}-1) (2311) − 1 0 9 -10^{9} 109~ 1 0 9 10^{9} 109
    unsigned long [int]无符号长整形4[0 ~ 4,294,967,295]0 ~ ( 2 32 − 1 ) (2^{32}-1) (2321)0 ~ 1 0 9 10^{9} 109
    [signed] long long [int]有符号双长整型8[-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807] − 2 63 -2^{63} 263~ ( 2 63 − 1 ) (2^{63}-1) (2631) − 1 0 18 -10^{18} 1018~ 1 0 18 10^{18} 1018
    unsigned long long [int]无符号双长整型8[0 ~ 18,446,744,073,709,551,615]0 ~ ( 2 64 − 1 ) (2^{64}-1) (2641)0 ~ 1 0 19 10^{19} 1019

2.二分查找函数

  • lower_bound( )

    lower_bound( begin,end,num)
    

    从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。

  • upper_bound( )

    upper_bound( begin,end,num)
    

    从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end

  • 注意事项:

    • 1.二分查找需要先进行排序
    • 2通过返回的地址减去起始地址begin,得到找到数字在数组中的下标
    • 3begin、end可以是指针,也可以是迭代器
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BkbK-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值