Primeira lista de exercícios (paa071-l1.pdf)
Exercício 1
Do menor até o maior crescimento assintótico (na mesma linha são funções de crescimento semelhante):
(1)
Exercício 2
(a)
e 
(b)
e 
Exercício 3
Exercício 4
(a)
Multiplicar(u, v, n) //multiplicar os numeros u e v, ambos de n bits
Se n == 0, retornar 0 // caso base
Dividir u em duas metades: a e b
Dividir v em duas metades: c e d
ac = Multiplicar(a,c,n/2)
ad = Multiplicar(a,d,n/2)
bc = Multiplicar(b,c,n/2)
bd = Multiplicar(b,d,n/2)
Retornar ac*2^n + (ad+bc)*2^(n/2) + bd
(b) Recorrência
(supondo que a multiplicacao por 2^n toma tempo n), logo complexidade 
(c) Recorrência
, complexidade 
Exercício 5
(a) Como mostrar que
?
(b)
, pois existem constantes a, b e
tal que
para 
(c) Acho intuitivamente que a afirmação é verdadeira, mas não sei como justificar.
Exercício 6
(a) Se n é par, temos
, se n é ímpar, temos
.
(b) Se n é par, temos
, se n é ímpar temos
.
(c)
- esse eu suei pra fazer, viu?
Exercício 7
Exercício 8
ContaMaior (no_heap, x, k)
se (valor(no_heap) < x)
numMaior++
se (numMaior > k)
retornar
ContaMaior(esq(no_heap),x,k)
se (numMaior > k)
retornar
ContaMaior(dir(no_heap),x,k)
variável global numMaior
numMaior = 0
ContaMaior(raiz_heap,x,k)
se (numMaior > k)
retornar "NAO"
senão
retornar "SIM"
Exercício 9
(a)
Ordenar C
Para cada elemento i de C, faça:
fazer uma busca binária em C pelo elemento de valor x-i
se existe o elemento x-i, retornar "SIM"
retornar "NAO"
(b)
A = primeiro_elemento(C), B = ultimo_elemento(C)
enquanto (A <= B) faça:
se (A+B == x) retornar "SIM"
senão se (A+B > X) B--
senão A++;
retornar "NAO"
Exercício 10
MenorDist(P, ini, fim) // menor distancia do conjunto de pontos P[ini] ate P[fim]
se (ini >= fim) retornar INFINITO
meio = (ini + fim)/2
menorEsq = menorDist(P,ini,meio), menorDir = menorDist(P,meio+1,fim)
menorTotal = minimo entre menorEsq e menorDir
// neste trecho, vamos pegar os resultados dos dois lados (esquerdo e direito),
// que ja vieram ordenados pelo valor da coordenada Y e vamos juntar em uma nova lista ordenada
// pelo valor da coordenada Y de cada ponto - procedimento semelhante ao mergesort
criar um vetor de pontos A de tamanho fim-ini+1
pEsq = ini, pDir = meio+1, c = 1
enquanto (pEsq <= meio E pDir < fim) faça:
ponto A[c] = ponto com menor Y entre P[pEsq] e P[pDir]
incrementar o ponteiro do lado escolhido e o valor de c
enquanto (pEsq <= meio) faça:
A[c] = P[pEsq], pEsq++, c++
enquanto (pDir < fim) faça:
A[c] = P[pDir], pDir++, c++
copiar A para P[ini]...P[fim]
para cada ponto i em P, faça:
Checar se a distância do ponto i para os 6 próximos pontos na lista é menor que o valor de "menor"
Se for, atualizar "menor"
retornar menor
Exercício 12
(a)
MaiorSeq[1] = 1
para i de 2 até N, faça:
MaiorSeq[i] = 1
para j de 1 até i-1, faça:
se (valor[i] > valor[j])
MaiorSeq[i] = maximo (MaiorSeq[i], MaiorSeq[j]+1)
retornar o maior valor encontrado em MaiorSeq
(b)
MaiorSeq[1] = Peso[1]
para i de 2 até N, faça:
MaiorSeq[i] = Peso[i]
para j de 1 até i-1, faça:
se (valor[i] > valor[j])
MaiorSeq[i] = maximo (MaiorSeq[i], MaiorSeq[j]+Peso[i])
retornar o maior valor encontrado em MaiorSeq
(c) Muito trabalhosa…
(d) Complexidade polinomial, 
(e) Sim, tá lá o algoritmo…
Exercício 13
Ordenar as sequencias S1 e S2
P1 = 1, P2 = 1, PS = 1
Enquanto (P1 <= N e P2 <= N) faça:
Se (S1[P1] == S2[P2]) faça:
S[PS] = S1[P1]
PS++, P1++, P2++
Senão se (S1[P1] < S2[P2])
S[PS] = S1[P1]
PS++, P1++
Senão
S[PS] = S2[P2]
PS++, P2++
Retornar S
Pior caso: 
O melhor caso depende do algoritmo de ordenação utilizado, podendo ser até 
Exercício 14
Minimo(ini, fim, eps)
vetor de pontos P[4] = { ini, (ini+fim)/3, 2*(ini+fim)/3, fim }
Se (fim - ini >= 2 * eps) retornar (ini+fim)/2
Achar o indice x do ponto em P que possui o menor valor [[$ F(P_i) $]]
Se X == 0, retornar Minimo(P[0],P[1],eps)
Se X == 3, retornar Minimo(P[2],P[3],eps)
retornar Minimo(P[X-1],P[X+1],eps)
Recorrência:
, logo
(b) Sim, pois o algoritmo depende somente do logaritmo de um dos valores da entrada
Exercício 15
(a) 
(b) Busca binária
, logo
.
Exercício 16
Um pé no saco, resolver a equação 
Exercício 19
Opa! Esse aqui enganou todo mundo! Na verdade, a equação toda
tem que ser calculada em tempo logaritmo em função da entrada N - qualquer algoritmo assintoticamente maior que isso será mais do que linear no tamanho da entrada (um algoritmo linear em função de N seria exponencial em relação ao tamanho da entrada!).
A equação pode ser desenvolvida assim:

Digamos
, temos então:

Como
é uma progressão geométrica de razão
, podemos calcular seu valor utilizando uma equação fechada:

Resta então o problema de calcular o valor de
em tempo, no máximo, logaritmico. Isso pode ser feito usando divisão e conquista (top-down), com a seguinte recorrência:

Feito isso, calculamos
e então podemos calcular facilmente, em tempo constante,
e o resultado final.





