Descrição do título
Insira n (n <5000000 e n é um número ímpar) números ai (0 <ai <1 0 9) n (n <5000000 e n é um número ímpar) números a_i (0 <a_ (i) <10 ^ 9)n ( n<. 5 0 0 0 0 0 0 , en é um número ímpar ) um número de palavras aEu( 0<umaEu<1 09 ),produzaokkdesses númerosO número de k é pequeno. O menor número é0 00 pequeno.
Por favor, tente não usar nth_element para escrever esta questão, porque o foco desta questão é praticar o algoritmo de dividir para conquistar.
Entrada e saída de amostra
Entrada
5 1
4 3 2 1 5
Produto
2
Link do tópico: P1923 Encontre o menor número k
Ideias:
Você pode classificar a matriz diretamente e gerar o k-ésimo.- Divida e conquiste: use a ideia de classificação rápida, escolha o primeiro número (ou o último número) como a temperatura de referência, coloque o número menor ou igual à referência à esquerda e o número maior que a referência em à direita, então o número do benchmark é localizado. A posição é a mesma que sua posição na matriz classificada. A operação acima é chamada de divisão e cada divisão retornará um número de referência. Se a posição do número de referência após a divisão for k, significa que o número de referência atual é o k-ésimo número e é emitido diretamente. Se a posição do número de referência atual for maior que k, significa que o k-ésimo maior número está no intervalo correto do número de referência e só precisa ser dividido novamente no intervalo correto. Caso contrário, no intervalo à esquerda, basta dividir e pesquisar no intervalo à esquerda.
Divida e conquiste o código:
//AC代码:
#include<iostream>
#include<cstdio>
using namespace std;
const int N=5e6+100;
int a[N];
//做一次划分,归位基准数
int p(int num[],int l,int r){
int temp=num[l];
while(l<r){
while(l<r&&num[r]>temp) r--;
num[l]=num[r];
while(l<r&&num[l]<=temp) l++;
num[r]=num[l];
}
num[l]=temp;
return l;
}
//分治查找第k小的数
int quicksort(int num[],int l,int r,int k){
int x=p(num,l,r);
if(x==k) return num[k];
return x>k ? quicksort(num,l,x-1,k) : quicksort(num,x+1,r,k);
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
printf("%d\n",quicksort(a,0,n-1,k));
return 0;
}
Use nth_element:
- Vendo esta função pela primeira vez, parece ser útil, familiarize-se com ela:
Arquivo de cabeçalho <algorithm>
void nth_element (RandomAccessIterator primeiro, RandomAccessIterator nth, RandomAccessIterator último);
void nth_element (first, nth, last);
Função: retornar o enésimo número no intervalo [primeiro, último).
//AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=5e6+100;
int a[N];
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
nth_element(a,a+k,a+n);
printf("%d\n",a[k]);
return 0;
}
- Pode-se ver que nth_element (a, a + k, a + n) retorna o elemento no "endereço a + k" original na matriz, e "a + 0" é o 0º menor.