Documente Academic
Documente Profesional
Documente Cultură
+ =
=
b a
b i
i b a k t b a k t
1
) , , 1 ( ) , , ( .
Prin urmare, numrul T poate fi calculat prin nsumarea valorilor ) , , ( j N k t pentru
N j ..., , 2 , 1 = :
=
+ = =
= =
N
j
j N
j i
N
j
i j N k t j N k t T
1 1 1
) , , 1 ( ) , , ( .
Complexitatea temporal a unui algoritm bazat pe formula recurent de mai sus este
) (
3
kN O . n cazul restriciilor problemei, numrul de operaii cerut de algoritm va fi de
ordinul
14
10 , mrime cu mult mai mare dect capacitatea de prelucrare a calculatoarelor
personale din laboratorul de informatic.
Pentru a reduce complexitatea temporal a algoritmului vom lua n considerare faptul c
pentru valorile lui b a i > funcia 0 ) , , ( = b a k t . n consecin, vom calcula doar sumele din
dreapta indicelui respectiv. n acest caz complexitatea algoritmului va fi ) (
2
N N O , iar
numrul cerut de operaii va fi de ordinul
8
10 , mrime comparabil cu capacitatea de
prelucrare a calculatoarelor din laboratorul de informatica.
Menionm faptul, c n procesul de efectuare a calculelor nu se cere memorarea tuturor
valorilor ) , , ( b a k t , fiind suficiente doar valorile iteraiei curente i termenii din dreapta, n
total circa 4 Megaoctei de memorie operativ.
Program Descompuneri;
{ Clasele 10-12 }
const MAXN = 1000;
const MODULO = 1000 * 1000 * 1000;
type TMatrice = array[1..MAXN, 1..MAXN] of longint;
var f: text;
n, m: longint;
a: TMatrice;
sumaLaDreapta: TMatrice;
i, j, k: longint;
res: longint;
existaElementNenul: boolean;
procedure scrieRezultat(q: longint);
{ Scrie rezultatul n fiierul de ieire i termin programul }
var f: text;
begin
assign(f, 'DESC.OUT');
rewrite(f);
writeln(f, res);
close(f);
halt(0);
end; { Scrie }
begin
fillchar(a, sizeof(a), 0);
fillchar(sumaLaDreapta, sizeof(sumaLaDreapta), 0);
assign(f, 'DESC.IN');
reset(f);
readln(f, n, m);
41
close(f);
{ construim cazul de baza: t[1, x, y] }
for j := 1 to n do
for k := 1 to n do
begin
if (j = k) then a[j, k] := 1 else a[j, k] := 0;
end;
{ partea principal: calcularea t[k, x, y] pentru k > 1 }
for i := 2 to m do
begin
{ calculm sumaLaDreapta }
for j := 1 to n do
for k := j downto 1 do
sumaLaDreapta[j, k] := (a[j, k] + sumaLaDreapta[j, k + 1]) mod
MODULO;
{ calculm t[i, j, k], care e memorat n a[j, k] }
existaElementNenul := false; {detector de valori nenule in a}
for j := 1 to n do
for k := 1 to n do
begin
a[j, k] := sumaLaDreapta[j - k, k + 1];
if a[j, k] > 0 then existaElementNenul := true;
end;
{ in cazul in care existaElementNenul e false, toate elementele lui a
}
{ calculate ulterior vor fi nule. Prin urmare, terminam calculele }
if not existaElementNenul then scrieRezultat(0);
end;
{ calculam raspunsul }
res := 0;
for k := 1 to n do
begin
inc(res, a[n, k]);
res := res mod MODULO;
end;
scrieRezultat(res);
end.
42
Radioul
Postul de radio Bitul Liber are la dispoziie n emitoare, amplasate n n localiti
distincte. Poziia fiecrui emitor i, n i ..., , 3 , 2 , 1 = , este definit prin coordonatele carteziene
ntregi ) , (
i i
y x .
Fiecare emitor are una i aceiai putere de emisie R. Evident, cu ct emitorul este
mai puternic, cu att este mai mare i distana la care se propag undele emise de el. n
scopuri didactice, se consider, c undele unui emitor de puterea R se propaga pn la
distana de R kilometri.
Dei emitoarele au una i aceiai putere R, fiecare din ele poate fi acordat n mod
individual s emit pe una din frecvenele disponibile frecvena F
1
sau frecvena F
2
.
Este cunoscut faptul, c undele radio interfereaz i, n consecin, dac un receptor este
supus aciunii concomitente a dou unde de aceiai frecven, calitatea recepiei scade brusc.
n general, conform regulilor de radiodifuziune, calitatea recepiei se consider bun doar
atunci, cnd nu exist nici un sector de arie nenul, pe care ajung unde radio, emise de dou
emitoare ce au aceiai frecven de emisie.
Este evident faptul, c pentru a extinde aria pe care pot fi recepionate emisiunile
postului de radio Bitul Liber, puterea de emisie R trebuie mrit. Concomitent, frecvenele
de emisie F
1
, F
2
pentru fiecare din emitoare trebuie alese n aa mod, nct s se asigure
calitatea recepiei emisiunilor respective.
Sarcin. Scriei un program, care, cunoscnd coordonatele emitoarelor, calculeaz
puterea maximal de emisie R, ce mai permite nc alegerea pentru fiecare din emitoare a
unor astfel de frecvene, nct se asigur calitatea recepiei.
Date de intrare. Fiierul text RADIO.IN conine pe prima linie numrul ntreg n.
Fiecare din urmtoarele n linii ale fiierului de intrare conine numerele ntregi x
i
, y
i
, separate
prin spaiu. Linia 1 + i a fiierului de intrare conine coordonatele emitorului i.
Date de ieire. Fiierul text RADIO.OUT va conine pe prima linie numrul real R, scris
cu o precizie nu mai mic de 10
-8
. Linia a doua a fiierului de ieire va conine n numere
ntregi, separate prin spaiu. Numrul care apare pe locul i de pe aceast linie va fi egal cu 1,
dac emitorul i trebuie s emit pe frecvena F
1
, i egal cu 2, dac emitorul respectiv
trebuie s emit pe frecvena F
2
. Dac problema admite mai multe soluii, n fiierul de ieire
se va scrie doar una din ele.
Exemplu.
Restricii. 200 1 3 s s n ;
4 4
10 , 10 s s
i
y x . Timpul de execuie nu va depi 2,0
secunde. Programul va folosi cel mult 64 Megaoctei de memorie operativ Fiierul surs va
avea denumirea RADIO.PAS, RADIO.C sau RADIO.CPP.
Rezolvare
Din enunul problemei rezult c puterea maximal nu poate depi jumtate din
distana dintre emitoarele aflate la cea mai mare distan unul de altul. Prin urmare, valoarea
RADIO.IN RADIO.OUT
4
0 0
0 1
1 0
1 1
0.70710678118654752
1 2 2 1
43
concret a lui R trebuie cutat n intervalul ] , 0 [
max
L , unde
max
L poate fi calculat conform
unor formule evidente:
) ..., , , min(
2 1 min n
x x x x =
;
) ..., , , min(
2 1 min n
y y y y =
;
) ..., , , max(
2 1 max n
x x x x =
;
) ..., , , max(
2 1 max n
y y y y =
.
1
2
) ( ) (
2
min max
2
min max
max
+
+
=
y y x x
L .
Presupunem, c avem la dispoziie o funcie ) (R Test , care ia valoarea 1, dac pentru
puterea de emisie R putem stabili frecvenele emitoarelor n aa mod, nct s garantm
calitatea recepiei, i 0 n caz contrar. Evident, avnd o astfel de funcie, putem calcula puterea
maximal prin metoda njumtirii, pornind de la intervalul iniial ] , 0 [
max
L i 2 /
max
L R = .
Pentru a construi funcia ) (R Test , reunim cu cte o linie emitoarele, distana dintre
care este strict mai mic de R 2 . Evident, oricare dou emitoare, ce sunt reunite printr-o
astfel de linie, trebuie s aib frecvene de emisie diferite.
n continuare, vom ncerca s partiionm mulimea emitoarelor n dou submulimi,
notate prin A i B. n cadrul fiecrei submulimi, emitoarele respective nu trebuie s fie
reunite ntre ele. Dac acest lucru ne reuete, funcia ) (R Test va lua valoarea 1. n caz
contrar, adic a rmas cel puin un emitor, ce nu poate fi incluse nici n submulimea A, nici
n submulimea B, funcia ) (R Test va lua valoarea 0.
1 ) ( = R Test 0 ) ( = R Test
Formarea submulimilor A i B poate fi simulat prin vopsirea fiecrui emitor n una
din cele dou culori: alb sau neagr. Iniial, vopsim un emitor arbitrar n culoare alb sau,
prin alte cuvinte, l includem n submulimea A. n continuare, determinm toate emitoarele,
reunite cu emitorul proaspt vopsit, i le vopsim n culoarea neagr sau, prin alte cuvinte, le
includem n submulimea B. n general, la fiecare pas al algoritmului, ce ncearc vopsirea
vecinilor emitorului curent n culoarea opus. n cazul tehnicii de programare Greedy,
complexitatea unui astfel de algoritm este ) (
2
n O .
44
Evident, dup determinarea valorii maximale R, pentru care funcia ) (R Test mai ea nc
valoarea 1, tuturor emitoarelor din mulimea A li se atribuie una din frecvene, de exemplu,
F
1
, iar celor din submulimea B cealalt frecven, de exemplu, frecvena F
2
.
Program Radio;
{ Clasele 10-12 }
var n : Integer;
var x, y : Array[1..1200] of LongInt;
var Freq : Array [1..1200] of Byte;
{ Frecventa asociata fiecarui emitator radio }
var f : Text;
i, j : Integer;
Left, Right, Med : Longint;
MaxSQDist : Longint;
function SQDist(i,j:Integer) : LongInt;
{ Intoarce patratul distantei intre emitatoarele i si j }
begin
SQDist := (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);
end;
function Test(R_SQ_4: Longint) : boolean; {parametrul este 4*R*R}
{ verifica daca cu raza de emisie R se poate atribui }
{ frecvente emitatoarelor }
var List : Array [1..1200] of Integer;
var ListSize : Integer; { numarul de noduri in lista }
var i, j, t,curent : Integer;
begin
FillByte(Freq, n, 0);
for i := 1 to n do
begin
if Freq[i]<>0 then continue; { frecventa pentru emitatorul i a fost }
{ aleasa deja }
Freq[i] := 1; {alege frecventa 1 pentru emitatorul i}
{ Initializeaza lista cu un singur element : i }
List[1] := i;
ListSize := 1;
j:=1;
while j <= ListSize do begin
curent := List[j];
for t:=1 to n do
begin
if (t<>curent) and ( SQDist(curent,t) < R_SQ_4 ) then
begin
if (Freq[t] = 0) then
begin
{adauga pe t in lista}
Inc(ListSize);
List[ListSize] := t;
Freq[t] := 3-Freq[curent]; { seteaza frecventa opusa }
end
else
if Freq[t] = Freq[curent] then exit(false);
{ am obtinut o contradictie de frecvente, functia Test }
{ va intoarce imediat false }
end;
end;
Inc(j);
end;
end;
45
Test := true;
end;
begin
{ Citeste datele de intrare }
Assign(f, 'RADIO.IN');
Reset(f);
Readln(f, n);
for i:= 1 to n do Readln(f, x[i], y[i]);
Close(f);
{ Gaseste distanta maxima intre virfuri}
MaxSQDist := 0;
for i:= 1 to n-1 do
for j:= i+1 to n do
if MaxSQDist < SQDist(i, j) then MaxSQDist := SQDist(i, j);
Left := 0;
Right := MaxSQDist + 1;
while Right>Left+1 do
begin
Med := (Left + Right) div 2;
if Test(Med)
then Left:=Med
else Right:=Med;
end;
{ mai apeleaza inca o data pentru a seta Freq[...] }
Test(Left);
{ Scrie raspunsul }
Assign(f,'RADIO.OUT');
Rewrite(f);
writeln(f,(sqrt(Extended(Left))/2):0:18);
for i:=1 to n do Write(f, Freq[i],' ');
writeln(f);
Close(f);
end.