题目描述
现有 n 个正整数,要求出这 n 个正整数中的第 k 个最小整数(相同大小的整数只计算一次)
输入格式
第一行为 n 和 k; 第二行开始为 n 个正整数的值,整数间用空格隔开。
输出格式
第k个最小整数的值;若无解,则输出 NO RESULT。
样例输入 1
10 3
1 3 3 7 2 5 1 2 4 6样例输出 1
3
提示
n≤10000,k≤1000,正整数均小于 30000。
代码如下
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 10010;
int n, k, q[N], cnt = 0;
void quick_sort(int q[], int l, int r)//快排算法,用sort函数也行
{
if (l >= r) return;
int x = q[(l + r) / 2], i = l - 1, j = r + 1;
while (i < j)
{
do i++; while (x > q[i]);
do j--; while (x < q[j]);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
int main()
{
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1); //对数列进行初始排序,未去重
for (int i = 0; i < n;i++)
{
while (q[i] == q[i + 1])
{
q[i] = q[i + 1]; //对重复数字操作,使后一个数覆盖前一个数
q[i + 1] = 0; //重复的数赋值为0
cnt++; //记录覆盖次数,即0的个数
quick_sort(q, 0, n - 1); //重新排序,将0移到最前
}
}
if (q[k + cnt - 1] == 0) printf("NO RESULT");//若没有第K小的数,则输出NO RESULT
else printf("%d", q[k+cnt-1]);
return 0;
}
1、解释一下为什么用while不用if
while (q[i] == q[i + 1])
{
q[i] = q[i + 1]; //对重复数字操作,使后一个数覆盖前一个数
q[i + 1] = 0; //重复的数赋值为0
cnt++; //记录覆盖次数,即0的个数
quick_sort(q, 0, n - 1); //重新排序,将0移到最前
}
举个简单的例子,一组数:2 2 2 2 3
用if的话只能覆盖1个相同的2,而while能循环覆盖直到只剩下1个2
2、关于将重复值赋值为0
由于题目说每个数据都是正整数,所以赋值为0最保险。理论上赋值为-1也可以,但是不知道为啥洛谷跑出来只有70分,如下图:
可能是排序的时候出了问题,哪位大佬来解答一下