Está en la página 1de 6

UNIVERSIDAD NACIONAL DE INGENIERÍA

Facultad de Ciencias
Escuela Profesional de Ciencia de la Computación
Ciclo 2019-2

Solucionario del examen parcial


Algoritmos CC262
n
X
1. Sea f (n) = j k log(j) para cierta constante k ∈ N; determine una
j=1
función simple g : N → N tal que f (n) = Θ(g(n)). Luego, calcule una
f (n)
constante c tal que lı́mn→∞ = 1.
cg(n)
Solución. Para una función creciente h : R → R, creciente y Sn =
Xn
h(k), se tiene, para n ∈ N, el estimado
k=1

Zn Zn
h(1) + h(x)dx ≤ Sn ≤ h(x)dx + h(n).
1 1

Aquı́ h(x) = xk log(x), cuya integral indefinida es (por integración por


partes)
xk+1 xk+1
Z
xk log(x)dx = log(x) − + C,
k+1 (k + 1)2
donde C es constante. Luego

nk+1 nk+1 1
log(n) − + ≤ f (n)
k+1 (k + 1)2 (k + 1)2

nk+1 nk+1 1
≤ log(n) − 2
+ + nk log(n).
k+1 (k + 1) (k + 1)2
Dividiendo
1 1 f (n)
1− + k+1
≤ 1
(k + 1) log(n) (k + 1)n log(n) k+1
nk+1log(n)

1 1 k+1
≤1− + k+1
+ .
(k + 1) log(n) (k + 1)n log(n) n

1
f (n)
De ahı́ lı́m = 1, es decir, la afirmación del enunciado
n→∞ 1 nk+1 log(n)
k+1
1
con g(n) = nk+1 log(n) y c = .
k+1
Luego, para n > n0

f (n) 1
− 1 < ,

1 k+1
k+1 n log(n) 2

de donde
1 3
nk+1 log(n) < f (n) < nk+1 log(n),
2(k + 1) 2(k + 1)

esto es f (n) = Θ nk+1 log(n) .

2. Escribamos todos los enteros positivos uno tras otro desde 1 como una
gran cadena:

12345678910111213141516171819202122232425262728293031323334...

a) Implemente un algoritmo para imprimir el k-ésimo dı́gito de esta


secuencia, de complejidad O(ln k) (Codeforces).
b) Demuestre que el algoritmo implementado funciona.

Solución. Primero veamos que la identidad


N
X xN +1 − 1
xk =
k=1
x−1

para x 6= 1 implica, derivando con respecto a x


N
X (N x − N − 1)xN + 1
kxk−1 =
k=1
(x − 1)2

Tenemos 9 números 1, . . . , 9 de una cifra, 90 números 10, . . . , 99 de dos


cifras, 900 números 100, . . . , 999 de tres cifras, y, en general, 9 · 10k−1
números de k cifras. Luego, para i fijo, de los números de k ≤ M cifras
tenemos un total de
M
X (9M − 1) · 10M + 1
h(M ) = 9 · 10k−1 =
k=1
9

2
dı́gitos, que representan los números de 1 a 99 . . . 9} = 10M +1 − 1.
| {z
M veces 9
Fijemos m ≥ 1 la posición del dı́gito a buscar. Sea s ≥ 1 tal que

h(s) = máx h(j) : j ≥ 1, h(j) ≤ m}.

De ahı́ h(s) ≤ m < h(s + 1).


Observamos que como para M ≥ 2

10M ≤ h(M ) ≤ M · 10M ,

un valor aproximado para s es el número de cifras de m.


Si h(s) = m, entonces el último dı́gito representado es 9 (de 10M +1 −1).
Si en cambio h(s) < m, entonces h(s) < m < h(s + 1) y m viene de
la representación de un número de s + 1 cifras. Se trata de m − h(s)
dı́gitos provenientes de la representación de números de s + 1 cifras.
Dividiendo este número entre s + 1, escribimos

m − h(s) = (s + 1)q + r, donde 0 ≤ r < s + 1.

Si r = 0, m es el último dı́gito de la representación de N = 10M +1 −1+q,


mientras que si r > 0, es el r-ésimo dı́gito de la representación de
N = 10M +1 + q.

/* En PARI/GP

Número de dı́gitos de la representación de números de


hasta M cifras
ene(M) =((9*M-1)*10^M+1)/9

/* Valor del argumento s que maximiza ene(s)<=m


maxene(m) = {
local(s);
s=length(digits(m));
while(ene(s)>m,s--);
while(ene(s)<=m,s++);
return(s-1);
}

/* Devuelve el dı́gito en la posición m */

3
digito(m) = {
local(dig);
local(s);
if(m<=9,dig=m,
s = maxene(m);
m -= ene(s);
print(m);
if(m==0,dig=9,
q = m\(s+1);
r = m % (s+1);
N = 10^s + q;
if(r==0, dig = (N-1) % 10,
dig = digits(N)[r]
)
)
);
return(dig);
}

3. Consideremos la recurrencia

T (n) = T (n/5) + T (4n/5) + O(n2 ).

a) Detalle el árbol de recurrencia para la recurrencia anterior. Estime


una cota T (n) = O(·).
b) Demuestre la cota superior anterior utilizando inducción.

Solución.

a) Obtenemos n

n 4n
5 5

n 4n 4n 16n
25 25 25 25

.. .. .. .. 4n 16n 16n 64n


. . . . 125 125 125 125

.. .. .. .. .. .. .. ..
. . . . . . . .

4
En cada nivel, los costos del término O(n) se escriben como ≤ cn2 ,
con c constante. El árbol tiene altura h = log5/4 n, siendo que se
establecen las hojas bajo la condición (4/5)h n ≤ 1. También se
establece que (1/5)h n ≤ 1, por lo que hay hojas en el nivel log5 n,
pero esto ocurre más rápido.
En los primeros niveles m (contando a partir de n = 0) los costos
acumulados son de
m      2     m
X m 1 k 4 m−k 2 1 2 4 2  17 m
cn = + cn2 = cn2 .
k=0
k 5 5 5 5 25

La suma estimada es por lo tanto


∞ 
X 17 k 25 2
T (n) ≤ · cn2 = cn ,
k=0
25 8

esto es T (n) = O(n2 ).


b) Para esta solución utilizamos
j n k  
4n
T (n) = T +T + f (n),
5 5

donde f (n) ≤ kn2 para cierta constante k. También puede usarse


d·e en lugar de b·c.
Por hipótesis inductiva (segundo principio de inducción), asumi-
mos que
T (i) ≤ ci2 para todo i < n.
Luego, reemplazando arriba
 n 2  4n 2
T (n) ≤ c +c + kn2
5 5
 17 
= c + k n2 .
25
Luego T (n) ≤ cn2 si
17
c + k ≤ c,
25
esto es, si c ≥ 25
8
k. Podemos por ejemplo fijar c = 25
8
k, lo que hará
funcionar la inducción.

4. Con respecto al algorithmo Heapsort:

5
a) ¿Dónde en un montı́culo (de máximo) se encuentra el menor ele-
mento del montı́culo, asumiento que todos los elementos son dis-
tintos?
b) Escriba una versión iterativa de Max-Heapify.

Solución.

a) En una hoja, dado que por condición ahijo ≤ apadre . Si el valor


mı́nimo ocurre en un nodo que no es una hoja, digamos ak ≤ al
para todo l, entonces, por condición de montı́culo,

a2k ≤ ak , a2k+1 ≤ ak ,

según corresponda, de donde a2k = ak y/o a2k+1 = ak . Es más,


todo el submontı́culo de raı́z en ak tomará ese mismo valor mı́nimo
ak en cada nodo.
Si todos los valores son distintos, solo queda que ak esté en una
hoja, dado que las desigualdades arriba serán todas estrictas para
l 6= k.
b) Max-Heapify(A, i)
while (true)
l = LEFT(i)
r = RIGHT(i)
if l <= A.heap-size and A[l] > A[i]
largest = l
else largest = i
if r <= A.heap-size and A[r] > A[largest]
largest = r
if largest = i break;
exchange A[i] with A[largest]
i = largest
end

También podría gustarte