Cod sursa(job #3241529)

Utilizator vralexRadu Vasilescu vralex Data 31 august 2024 11:22:36
Problema Statistici de ordine Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.49 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void swap(int* x, int* y) {
  int aux;
  aux = *x;
  *x = *y;
  *y = aux;
}

// O(n):
int partition(int* nums, int numsSize, int pivotIndex) {
  /* End will be a pointer to the first element that is not in the
  part of nums that contains elements that are greater than the pivot.
  */
  int *current, *end = nums;
  // Make an arbitrary choice for the pivotIndex.
  // Make the pivot be the last element of the array:
  swap(&nums[pivotIndex], &nums[numsSize - 1]);
  // Current will increase by 4, while it is less than nums + 4 * (numsSize-1):
  for (current = nums; current < nums + (numsSize - 1); current++)
    if (*current < nums[numsSize - 1]) {
      swap(current, end);
      end++;  // Add 4 bytes.
    }
  // Put the pivot immediately after the sequence of elements that are > than
  // it.
  // If multiple elements are equal to the pivot's value, only the first one is
  // guaranteed to be after the greater elements.
  swap(&nums[numsSize - 1], end);
  return end - nums;  // Return the position of the pivot.
}

// T(n) = T(n/a) + O(n) (if one recursive call is made).
int findKthSmallest(int* nums, int numsSize, int k) {
  int pivotIndex = rand() % numsSize;
  int pos = partition(nums, numsSize, pivotIndex);
  // If the chosen pivot is at index k-1 after partitioning,
  // then it is the k-th largest element.
  if (pos == k - 1) return nums[pos];
  /* If pos < k - 1, we have less than k-1 elements that are greater than
  the pivot. So the searched number is smaller than the pivot.
  The numbers that are smaller than the pivot are found between
  nums + pos + 1 and nums + numsSize - 1 (numsSize-1-pos)
  In the other part of the array we have already found the greatest pos+1
  numbers in the array. Hence, we need to find the k-pos-1-th greatest
  element in the remaining array.
  */
  if (pos < k - 1)
    return findKthSmallest(nums + pos + 1, numsSize - 1 - pos, k - pos - 1);
  else  // pos > k-1
  {
    // More than k-1 numbers are greater than the pivot.
    // Search in the greater than pivot part: nums, ... nums + pos - 1
    return findKthSmallest(nums, pos, k);
  }
}

int main() {
  int *v, n, k;
  int i;
  FILE *fp_in, *fp_out;
  fp_in = fopen("sdo.in", "r");
  fp_out = fopen("sdo.out", "w");
  fscanf(fp_in, "%d %d\n", &n, &k);
  v = (int*)malloc(n * sizeof(int));
  srand(time(NULL));
  for (i = 0; i < n; i++) fscanf(fp_in, "%d", &v[i]);
  fprintf(fp_out, "%d", findKthSmallest(v, n, k));
  fclose(fp_in);
  fclose(fp_out);
  return 0;
}