完美数列
第一题
给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤m**p,则称这个数列是完美数列。
现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入格式:
输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数。第二行给出 N 个正整数,每个数不超过 109。
输出格式:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
输入样例:
10 8
2 3 20 4 5 1 6 7 8 9
输出样例:
8
题目分析:原先我的想法是假设最长数列就是n,然后有序数组进行两端判断。想法是有,但是代码不知道怎么写
柳神是用双指针,这题其实双指针的时间复杂度都能上n^2^了,所以这里双指针要优化一下,用res来存放当前最长长度,
第一重循环用i=0~n,第二层循环j就不能从0开始了否则太慢了,而且重复了。
第二重循环用j=i+res~n
第二重循环中判断到不符合条件就直接跳出了,因为这是个有序数组,之后的数据也都不成立了。
所以做这两个优化后,效率杠杠的👍
#include<iostream>
#include<algorithm>
using namespace std;
int main(void){
int n;
long p;
cin >> n >> p;
int a[n],i,j;
for(i = 0; i < n ;i++) cin >> a[i];
sort(a,a+n);
int tmp = 0,res = 0;
for(i = 0; i < n ;i++){
for(j=i + res;j < n;j++)
if(a[i] * p >= a[j] && (tmp = j - i + 1) > res) res = tmp;
else break;
}
cout << res;
return 0;
}
归并与插入
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
输入格式:
输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。
输出格式:
首先在第 1 行中输出Insertion Sort
表示插入排序、或Merge Sort
表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。
输入样例 1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出样例 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
输入样例 2:
10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6
输出样例 2:
Merge Sort
1 2 3 8 4 5 7 9 0 6
题目分析:
这题由于插入排序是从后往前的,所以插入排序的中间序列一定是,前段有序,后段和原序列相同。
归并排序的话没有直观的规律,这里不是插入就是归并了,极端情况的数据没有意义
这里归并排序的下一个序列,由于无法判断是第几次归并,所以只能用原序列进行一次次归并比较中间序列,直到全部吻合
这里值得学习的是,用c++的sort函数,直接忽略了插入排序和归并排序的具体排序细节,运行效率可能没有她两好,不过开发效率很香
#include<iostream>
#include<algorithm>
using namespace std;
int main(void){
int n;
cin >> n;
int a[n],b[n],i,j;
for(i=0;i < n;i++) cin >> a[i];
for(i=0;i < n;i++) cin >> b[i];
for(i=0;b[i] <= b[i+1];i++);
for(j=i + 1;b[j] == a[j] && j < n;j++);
if(j == n){
cout << "Insertion Sort" << endl;
sort(a,a+i+2);
}else{
cout << "Merge Sort" << endl;
int flag = 1 , k = 1;
while(flag){
flag = 0;
for(i = 0; i < n ; i++) if(a[i] != b[i]) flag = 1;
k *= 2;
for(i = 0; i < n / k ; i++) sort(a + i * k, a + (i+1)*k );
sort(a + n / k * k, a + n); // n / k 不整除的情况下,剩余部分给计算进去
}
}
for(i=0;i < n;i++) {
if(i != 0) cout << " ";
cout << a[i];
}
return 0;
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com