Temat: Zagadka/i ;)
Karim A.:
Przyznam, poniosło mnie z podkreślaniem wagi tego, że tablica jest duża i należy szukać rozwiązania liniowego. Niemniej jednak, fajną dyskusję sprowokowałem :)
Nic Cie nie poniosło. Rozwiazanie zagadki jest następujące.
zadana liczba : Suma
badany jest ciąg liczb na pod względem wiadomej Sumy
tworze zbior liczb do przechowywania wartosci które juz sie pojawily;
Na razie pusty.
(
ilosc mozliwych liczb calkowitych (w komputerze
oczywiscie) jest stala (i znana) wiec czas potrzebny
na odnalezienie liczby w zbiorze bedzie ograniczony
przez stałą
)
pobieram kolejną liczbe i zapisuje do zmiennej X
szukam dopelnienia do sumy (suma-X):
jest jest w zbiorze
to return true;
a jak nie nie
to dopisuje zapisuje badana liczbe do zbioru
i to wszystko
Złożoność:
- jeden przebieg - N
- max dwa poszukiwania w zbiorze - stała 2
- przeszukiwanie zbioru - stala lub ograniczona stalą
A w C++ to mniej więcej tak (alem nie kompilowal tego):
const int MAX = .... // rownie dobrze moge brac dane
int Dane[MAX]; // ze strumienia
int suma = ... // szukana suma
set<int> dotychczas_byly;
for (int ii=0; ii<MAX; i++) {
int X=Dane[ii];
if (dotychczas_byly.find(Suma-X) )
return true;
else
dotychczas_byly.insert(X);
}
return false; // przeszukalim i nieznalezlim;
UWAGA; jesli typ danych wejsciowych bedzie mial mala liczbnosc np. unsigned char, (czyli zajmowal malo bajtow) to jako zmienna zbiorowa mozna zastosowac tablice)
dla unsigned char:
bool dotychczas_byly[256];
for (int ii=0;i<256;i++)
dotychczas_byly=false;
Wtedy badanie i uzupelnianie zbioru b. wygladc:
if ( dotychczas_byly[Suma-x] )
return true;
else dotychczas_byla[x]=true;
Zliozonosc obliczeniowa STALA i mala!
P.S.
1. Świat algorytmów jest swiatem idealnym i dlatego pytanie o dostępne zasoby
uważam za nietakt :)
2. Jeśli kogoś nie zadowala pkt. 1 to małe zużycie pamięci może zrekompensować
złożonoscią obliczeniową albo na odwrót. W życiu jest zwykle cóś z cóś.