[PJWSTK] ASD – Kolokwium 4 – Rozwiązanie

Czwarte zadanie z ASD:

Rozważmy uporządkowany ciąg C różnych liczb naturalnych długości n>0 oraz wybrany element c tego ciągu. Dalej przyjmujemy, że algorytm wyszukiwania binarnego jest zgodny z poniższym (zakładamy indeksowanie elementów ciągu od wartości początkowej 0):

1  l:=0, r:=n-1, m:=(l+r)/2;
2  
3  while (C[m]!=c) {
4    if (C[m]<c)
5      l:=m+1;
6    else
7      r:=m-1;
8    m:=(l+r)/2;
9  }

Wprowadzamy teraz modyfikacje algorytmu wyszukiwania binarnego polegającą na tym, że w miejsce instrukcji zawartych w wierszach 4-8 w pewnej iteracji rozważanego algorytmu wykonujemy sekwencyjne przeszukanie pozostałego fragmentu ciągu począwszy od pozycji l aż do skutku, tj.

4  while (C[l]!=c)
5    l:=l+1;
6
7  m:=l;
8

Załóżmy, że koszt wykonania algorytmu wszykiwania binarnego (zarówno bez i z w/w modyfikacją) oznaczamy jako COST i definiujemy zależnością:

COST=sqrt(a)*div+cmp

gdzie a jest pewną dodatnią stałą naturalną, sqrt(a) jest funkcją, której rezultatem jest część naturalna z pierwiastka z liczby a oraz div i cmp to odpowiednio liczba operacji dzielenia przez 2 (wiersze 1 i 8) oraz liczba operacji prówniania z elementami ciągu C występujacych w rozważanym algorytmie (wiersze 3 i 4).

Wyznacz najmniejszą możliwą wartość stałej a, dla której wykonanie algorytmu wyszukiwania binarnego z modyfikacją sekwencyjną niezależnie od wybranej iteracji zastosowania tej modyfikacji, prowadzi w każdym przypadku do rozwiązania o koszcie mniejszym niż standardowe wyszukiwanie binarne (tj. algorytm bez modyfikacji sekwencyjnej).

Wejście

Wiersz zawierający ciąg liczb naturlanych oddzielonych znakiem odstępu/spacji (ASCII kod 32) i zakończony znakiem końca pliku (EOF), gdzie:

  • pierwszy element ciągu definiuje długość n ciągu C tak, że n zawarte jest w przedziale wartości [1,10^6],
  • kolejne elementy ciągu reprezentują elementy właściwe ciagu C i zawarte są w przedziale wartości [0,10^9],
  • ostatni element ciągu wejściowego reprezentuje wybrane element c ciągu C.

Wyjście

Wiersz zawierajacy pojedynczą liczbę naturalną nie większą niż 10^9 będącą rozwiązaniem postawionego problemu (wiersz pusty w przypadku braku rozwiązania).

Złożoności i limity

Złożoność czasowa O(n), złożoność pamięciowa O(n), gdzie n jest długością ciągu podanego na wejściu. Fizyczny limit pamięci zależny od rozmiaru danych wejściowych i ograniczony przez 4n B + 1 KB.

Przykład 1

Wejście:
3 1 2 3 3

Wyjście:
9

Przykład 2

Wejście:
10 0 1 2 3 4 5 6 7 8 9 0

Wyjście:
1

Rozwiązanie w C++:

#include <stdio.h>

int main()
{
    int n;
    fscanf(stdin, "%i", &n);
	int* C = new int[n];
	for(int i = 0; i < n; i++)
	{
		fscanf(stdin, "%i", &C[i]);
	}
	int c;
	fscanf(stdin, "%i", &c);
	n--;
	int l = 0;
	int r = n;
	int m = (l + r) / 2;
	int binarneDzielenie = 1;
	int binarnePorownania = 1;
	while(C[m] != c)
	{
		binarnePorownania++;
		if(C[m] < c)
			l = m + 1;
		else
			r = m - 1;
		binarnePorownania++;
		m = (l + r) / 2;
		binarneDzielenie++;
	}
	int indeksWyniku = m;
	l = 0;
	r = n;
	m = (l + r) / 2;
	int minimalneA = 0;
	int sekwencyjneDzielenie = 1;
	int sekwencyjnePorownania = 1;
	while(C[m] != c)
	{	
		sekwencyjnePorownania++;
		int iloscPorownan = sekwencyjnePorownania + indeksWyniku - l + 1;
		int a = ((iloscPorownan - binarnePorownania) / (binarneDzielenie - sekwencyjneDzielenie)) + 1;
		if(a > minimalneA)
			minimalneA = a;
		if(C[m] < c)
			l = m + 1;
		else
			r = m - 1;
		sekwencyjnePorownania++;
		m = (l + r) / 2;
		sekwencyjneDzielenie++;
	}
	fprintf(stdout, "%i", minimalneA * minimalneA);
	return 0;
}
Ten wpis został opublikowany w kategorii PJWSTK, PJWSTK - ASD. Dodaj zakładkę do bezpośredniego odnośnika.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *