Page 1

Trabajos finales  de  la  materia  DSC  G3     Utilizando   todos   los   conocimientos   adquiridos   durante   el   curso,   resuelva   el   problema   que   aparece  a  continuación  utilizando  como  lenguaje  de  programación  C/C++.  Para  solucionar  el   problema  debe:   1. Diseñar   los   algoritmos   necesarios   que   permitan   resolver   el   problema   planteado,   utilizando   alguna   de   las   técnicas   estudiadas.   Debe   indicar   qué   técnica   utilizó   y   justificar   su   respuesta   en   cada   caso.   Puede   ser   que   utilice   varios   algoritmos   para   resolver  partes  parciales  del  problema,  cada  uno  con  técnicas  diferentes.   2. Implementar   los   algoritmos   diseñados   en   C/C++   de   la   manera   más   óptima   posible   y   mostrar  su  funcionamiento  en  un  programa  interactivo.   3. Calcular  sus  tiempos  de  ejecución  y  su  complejidad  algorítmica  para  los  casos:  mejor,   peor   y   promedio,   analizando   cuando   ocurre   cada   uno   de   los   casos   anteriores.   Esto   aplica  para  cada  algoritmo  diseñado.  

Según  seleccionaron  en  el  chat,  a  continuación  aparece  el  problema  asignado  a  cada  equipo:   Mayra y José Luis (7) Dante, Emilio y Luis Armando (3) Edgar y Olga (4) Américo y José Jaime (2) Ernesto Lee y Adalberto (5) Carlos y Javier Aurelio (1) Rubén y Leobano (6)

Equipo  1.     Hay   un   campo   en   el   cual   hay   postes   clavados   en   el   suelo,   en   ubicaciones   en   apariencia   arbitrarias.   Un   colono,   al   que   le   gustan   particularmente   los   campos   triangulares,   desea   establecer   su   chacra   allí.   Dada   su   preferencia,   y   el   hecho   de   que   no   parece   haber   otros   colonos,  decide  delimitar  su  chacra  eligiendo  los  tres  postes  que  hagan  máxima  su  superficie.     El   archivo   chatri.in contiene   la   lista   de   las   coordenadas   x   e   y,   enteras,   no   negativas,   menores  que  1000,  de  cada  poste,  separadas  por  un  espacio  en  blanco,  en  una  línea  cada  par.   El   fin   de   la   lista   está   indicado   por   un   par   –1 –1,   que   no   forma   parte   de   la   lista.   Hay   a   lo   sumo   500  postes.     En   el   archivo   chatri.out debe   grabar,   en   cualquier   orden,   las   coordenadas   de   los   tres   postes   que   hacen   máxima   la   superficie   de   la   chacra   triangular   que   determinan   esos   postes,   en   una  línea  cada  par  de  coordenadas.     Ejemplo:     Si,  chatri.in contiene:    


0 4 1 7 3 1 3 8 5 10 5 5 6 2 8 9 10 7 10 3 -1 -1 El archivo  chatri.out podría  contener:     1 7 3 1 10 7 Equipo  2.   Se   desea   escribir   un   programa   para   evaluar   expresiones   que   representan   operaciones   entre   conjuntos  de  números  naturales  menores  que  1000.  Los  conjuntos  están  expresados  por  listas   de  valores  separados  por  comas,  y  encerrados  entre  llaves.  Los  siguientes  son  cuatro  ejemplos   de  conjuntos  representados  de  este  modo:  {1,3,9,77} {} {7,1,193} {55}.     Note   que   como   las   listas   representan   conjuntos,   {1,3,9,77} y {77,3,1,9} representan  el  mismo  conjunto  y  pueden  utilizarse  indistintamente.     Una  expresión  puede  ser  simplemente  una  lista.  Por  ejemplo,  {7,1,193} es  una  expresión   cuyo  resultado  es  ese  mismo  conjunto.     Una   expresión   puede   también   formarse   con   dos   listas,   o   expresiones,   separadas   por   *,   que   representa   la   intersección   de   conjuntos,   es   decir   el   conjunto   de   los   elementos   comunes   a   ambos.  Por  ejemplo,  {1,3,9,77}*{7,1,193} da  como  resultado  {1}.     Con   igual   forma   constructiva,   pero   usando   +,   se   calcula   la   unión,   es   decir   el   conjunto   de   los   elementos  que  están  al  menos  en  uno  de  los  dos  conjuntos.  Por  ejemplo,   {1,3,9,77}+{7,1,193} da  como  resultado  {1,3,7,9,77,193}.     Cuando   hay   múltiples   operaciones   seguidas,   se   evalúa   de   izquierda   a   derecha.   Por   ejemplo,   {1,3,9,77}*{7,1,193}+{55} da  como  resultado  {1,55}.     Para   expresar   explícitamente   un   orden,   cualquier   expresión   puede   encerrarse   entre   paréntesis.   Por  ejemplo,  {1,3,9,77}*({7,1,193}+{55}) da  como  resultado  {1}.     Estas   reglas   pueden   aplicarse   repetidamente.   Por   ejemplo,   las   siguientes   expresiones   son   válidas:  (((({})))), (({1}+{2,3})*({4,5,6}+{})), {}+({}+{})+({5}).    


El programa   a   escribir   debe   leer   una   expresión,   de   hasta   250   caracteres,   del   archivo   expres.in,   evaluarla,   y   grabar   el   conjunto   resultante   como   una   lista   en   el   mismo   formato   que  la  entrada,  en  el  archivo  expres.out.     Por  ejemplo,  si  expres.in contiene:   (({3}+({1,4,2}))*({1,2,3,4,5}*{4,3,2,5}*{2,3,4,5,6}+{}))+{}   el  archivo  expres.out podría  contener   {2,3,4}         Equipo  3.   Se   cuenta   con   un   mueble   para   biblioteca   de   N   estantes   y   M   libros   de   distinta   altura.   Por   simplificación,   todos   los   libros   tienen   el   mismo   ancho   de   forma   tal   que   a   lo   sumo   entren   k   libros  por  estante,  todos  “parados”.  Además  todos  los  libros  caben  en  profundidad  y  la  altura   de  los  estantes  es  la  suficiente  para  que  calce  cualquier  libro.     El   objetivo   es   ordenarlos   (parados),   de   forma   que   queden   "lo   más   prolijo   posible".   Esto   significa   encontrar   una   distribución   de   los   M   libros   en   los   N   estantes   tal   que   sea   mínima   la   suma   de   los   valores   absolutos   de   las   diferencias   de   altura   de   un   libro   con   su   vecino   de   la   derecha,  si  hay.  A  este  valor  lo  llamaremos  “número  de  prolijidad”.     Por  ejemplo  si  tuviese  5  libros  con  las  alturas:  5  5  6  8  9,  a  colocar  en  2  estantes,  el  “número  de   prolijidad”  sería  2,  p.  ej.  colocando  6  5  5  en  el  primer  estante  y  8  9  en  el  segundo.       Considere  que:   Hay   más   libros   que   estantes   y   alcanza   el   lugar   en   el   mueble   para   guardarlos   todos.   (O   sea   N   <   M  y  K  x  N  >=  M)   Además  se  restringen  los  valores  según:   0  <  K  <=  50;  0  <  N  <=  10;  0  <  M  <=  500     La  altura  es  un  número  entero  tal  que:  0  <  altura  <=  1000     El  archivo  de  entrada  libros.in posee:   1)  N  M  K,  en  el  primer  renglón,  separados  por  un  espacio  en  blanco.   2)  la  altura  de  los  M  libros,  uno  por  renglón.     El  archivo  de  salida  libros.out tendrá  solo  el  “número  de  prolijidad”     Si libros.in tiene: 3 10 4 58 14 20 35789 10


libros.out tendrá 12 Equipo  4.   En   la   entrada   a   una   fiesta   hay   un   portero,   que   controla   una   fila   de   damas   y   otra   de   caballeros.   El  portero  puede  decidir  dejar  entrar:   -­‐ a  la  primer  dama  de  la  fila   -­‐ al  primer  caballero  de  la  fila   -­‐ a  la  pareja  formada  por  la  primer  dama  y  el  primer  caballero  de  la  fila.     El   portero   sabe   qué   damas   y   caballeros   simpatizan   entre   sí,   y   sabe   dónde   están   en   sus   filas.   Tiene  la  idea  de  dejar  entrar  las  damas  y  los  caballeros  de  forma  tal  de  hacer  pasar  en  pareja   la  mayor  cantidad  de  damas  y  caballeros  que  simpaticen  entre  sí.  Por  ejemplo,  si  en  las  filas   están  las  siguientes  personas:     1 2 3 4 5

Mónica María Luisa Leticia Josefa

1 2 3 4

Juan Pedro Augusto Felipe

y el  portero  sabe  que:   Mónica y Felipe simpatizan María y Augusto simpatizan María y Felipe simpatizan Luisa y Juan simpatizan Leticia y Augusto simpatizan Leticia y Juan simpatizan Josefa y Felipe simpatizan

(pobre Pedro!)  el  portero  debe:    

dejar dejar dejar dejar dejar dejar

pasar sola a Mónica pasar sola a María entrar a Luisa con Juan entrar solo a Pedro entrar a Leticia con Augusto entrar a Josefa con Felipe.

Debemos ayudar   al   portero   escribiendo   un   programa   que   determine   la   cantidad   máxima   de   parejas  que  puede  dejar  entrar  e  identifique  la  primera  de  tales  parejas.   Datos  de  entrada   Se  recibe  un  archivo PORTERO.IN del  directorio  actual,  que  contiene:   •  Primera  línea:  el  número  n  de  damas  en  la  fila  de  damas  (n  <=  1000)   •  n  líneas,  cada  una  con  el  nombre  de  una  dama  (hilera  de  hasta  30  caracteres  usando  letras  y   dígitos),  la  primer  línea  corresponde  a  la  primer  dama.   •  una  línea  con  el  número  m  de  caballeros  en  la  fila  de  caballeros  (m  <=  1000)     caballero  (hilera  de  hasta  30   caracteres  usando  letras  y  dígitos),  la  primer  línea  corresponde   al  primer  caballero.  


• una   línea   con   el   número   p   de   parejas   dama   /   caballero   que   simpatizan   entre   sí   (0   <   p   <=   1000)   •  p  líneas,  cada  una  con  una  pareja  dama  /  caballero,  separados  por  un  guión.     Aclaraciones:  No  existen  dos  nombres  iguales.     Datos  de  salida   El  programa  debe  generar  el  archivo  PORTERO.OUT, en  el  directorio  actual,  con:   •   una   línea   con   la   cantidad   máxima   de   parejas   (que   simpatizan   entre   sí),   que   puede   hacer   pasar  el  portero.   •   una   segunda   línea   con   los   nombres   de   alguna   pareja   (simpatizantes   entre   sí),   separados   por   un  espacio,  que  el  portero  puede  hacer  pasar  primero  si  quiere  maximizar  las  parejas.     En  caso  de  que  no  existan  parejas  que  simpaticen  entre  sí,  la  primera  línea  debe  decir  0  y  no   debe  haber  segunda  línea.     Ejemplo:     En  el  caso  de  que  el  archivo PORTERO.IN contenga:   5 Mónica María Luisa Leticia Josefa 4 Juan Pedro Augusto Felipe 7 Mónica-Felipe Josefa-Felipe María-Augusto María-Felipe Luisa-Juan Leticia-Augusto Leticia-Juan el  archivo PORTERO.OUT deberá  contener:   3   Luisa Juan   Equipo  5.     Una  clínica  de  salud  quiere  implementar  un  sistema  de  urgencias  acorde  a  las  necesidades  de   sus   pacientes.   Para   lo   anterior,   ha   decidido   implementar   un   sistema   formado   por   tres   elementos  principales:  un  conjunto  de  médicos  con  especialidades  diferentes  (pueden  existir   varios   médicos   de   la   misma   especialidad)   que   siempre   están   de   guardia   en   urgencias,   un  


sistema automatizado   de   diagnóstico   (en   lo   sucesivo,   SAD)   que   permitirá   a   cada   paciente   decidir   con   cuál   médico   debe   pasar   para   ser   atendido   según   sus   síntomas,   y   una   fila   de   pacientes   que   se   van   atendiendo   en   el   mismo   orden   en   que   van   llegando.   Dentro   de   los   requerimientos  iniciales  del  sistema  se  tienen  los  siguientes:   § De  cada  médico  se  conoce  su  nombre,  apellidos  y  especialidad.  Pueden  existir  tantos   médicos   de   guardia   como   se   necesiten,   incluso   varios   médicos   de   la   misma   especialidad.   § Cuando   un   paciente   llega   a   la   clínica,   se   registra   en   el   sistema   con   su   nombre,   apellidos,   edad   y   teléfono.   Posteriormente   consulta   al   SAD,   el   cual   le   hará   una   pregunta  y  el  paciente  debe  responder  si  o  no.  En  dependencia  de  cada  respuesta,  el   SAD   irá   haciendo   más   preguntas   hasta   llegar   a   una   decisión   de   determinar   en   cuál   especialidad   debe   ser   atendido   el   paciente.   Una   vez   que   el   SAD   determina   la   especialidad,   debe   enviar   al   paciente   con   el   médico   de   dicha   especialidad,   que   tenga   menos   pacientes   en   espera.   A   medida   que   el   paciente   interactúa   con   el   SAD,   este   último  va  registrando  junto  con  los  datos  del  paciente,  todas  las  preguntas  realizadas   al   paciente   y   las   respuestas   obtenidas   del   mismo,   para   que   el   médico   que   lo   atienda   pueda   tener   una   idea   previa   de   sus   padecimientos.   Dos   pacientes   que   respondan   exactamente   igual   a   las   preguntas   del   SAD   deben   atenderse   por   un   médico   de   la   misma  especialidad,  pero  no  necesariamente  por  el  mismo  médico.   § El   sistema   debe   utilizar   todos   los   conceptos   de   POO,   programación   genérica,   sobrecarga  de  operadores,  estructuras  y  algoritmos  de  la  STL,  uso  y  manipulación  de   streams,   seriación   de   objetos,   manipulación   de   errores   con   validación   y   excepciones   (según  sea  el  caso).   § El  código  debe  estar  optimizado.     Diseñe  y  programe  una  aplicación  que  permita:   a) Ingresar  médicos  al  cuerpo  de  guardia.   b) Crear  la  base  de  información  del  SAD.   c) Registrar  un  paciente  nuevo;  su  interacción  con  el  SAD    y  pasarlo  a  la  lista  de  espera   del  médico  correspondiente.   d) Atender  un  paciente  por  el  médico  asignado  (al  ser  atendido,  el  paciente  deja  la  clínica   y   se   retira   a   su   casa).   Cuando   un   paciente   es   atendido,   su   registro   se   queda   almacenado  en  el  sistema  para  cuestiones  estadísticas.   e) Generar  un  reporte  en  cualquier  momento  que  incluya:   a. Cantidad  de  médicos  de  guardia   b. Para   cada   médico,   su   nombre,   apellidos,   especialidad,   cantidad   de   personas   que   tiene   en   espera,   cantidad   de   personas   que   ya   ha   atendido,   y   de   cada   persona  su  nombre,  apellidos  y  edad.   c. Por  ejemplo,  debe  mostrarse  una  salida  como  la  siguiente:   Médicos  de  guardia:  3   Patricio  Martínez  (Cardiología)   Personas  atendidas:  2   1. Emeregildo  Estévez,  54  años   2. Lisbet  Esquivel,  87  años   Personas  en  espera:  1   1. Salvador  Imer,  60  años   Josefina  Almarante  (Pediatría)   Personas  atendidas:  1   1. Lisa  Elena  Bustamante,  5  años   Personas  en  espera:  1  


1. Camilo Juárez,  8  años   Emilia  Alvarez  (Pediatría)   Personas  atendidas:  0   Personas  en  espera:  1   1. Santiago  Esquivel,  12  años     f) Generar   un   reporte   que   muestre   la   cantidad   de   personas   que   han   sido   atendidas,   agrupadas  por  especialidad.   a. Por  ejemplo:   Cantidad  de  personas  atendidas  por  especialidad:   § Ginecología:  0   § Pediatría:  1   § Cardiología  :  2     g) Generar   un   reporte   de   todas   las   personas   que   han   sido   atendidas   (por   todos   los   médicos),  ordenadas  ascendentemente  por  su  edad,  mostrando  su  nombre,  apellidos,   edad  y  especialidad  del  médico  que  la  atendió:   a. Por  ejemplo,  debe  salir  un  listado  como  el  siguiente:   Personas  atendidas:   1. Lisa  Elena  Bustamante,  5  años,  Pediatría   2. Emeregildo  Estévez,  54  años,  Cardiología   3. Lisbet  Esquivel,  87  años,  Cardiología     h) Almacenar  el  estado  actual  del  sistema  (médicos,  personas  en  espera  de  ser  atendidas,   personas   que   ya   fueron   atendidas   y   la   base   de   datos   de   preguntas   del   SAD)   como   mecanismo  de  respaldo  de  la  información  ante  cualquier  falla  que  pueda  surgir.   i) Restablecer  el  estado  del  sistema  al  punto  en  que  se  encontraba  antes  de  ocurrir  una   falla.     Equipo  6.     Se   quiere   modelar   un   mapa   de   carreteras,   donde   aparezcan   las   ciudades   y   todas   las   rutas   que   las   conectan   entre   sí.   De   cada   ruta   se   conoce   la   distancia   en   kilómetros   y   de   cada   ciudad   se   conoce  su  número  de  habitantes,  nombre  y  año  de  fundada.   Programe  una  aplicación  interactiva  que  permita:   • • • •

• • •

Construir el  mapa  de  carreteras.   Determinar  la  población  total  del  país.   Determinar  la  ciudad  más  antigua  y  la  más  joven.   Dada  dos  ciudades  A  y  B,  determinar  si  se  puede  llegar  a  la  ciudad  B  partiendo  de  la   ciudad   A.   En   caso   de   ser   posible   indicar   todas   las   posibles   rutas   (simples)   con   los   nombres  de  las  ciudades  que  incluye  y  la  distancia  de  cada  tramo,  así  como  la  distancia   total  a  recorrer  por  cada  ruta.   Dada  una  ciudad,  determinar  cuál  es  la  ciudad  más  cercana  y  cuál  es  la  más  distante.   Actualizar   el   mapa,   eliminando   ciudades   y/o   carreteras,   teniendo   en   cuenta   que   las   ciudades  se  pueden  quedar  aisladas.   Encontrar  la  ruta  más  corta  entre  dos  ciudades,  indicando  las  ciudades  intermedias  y   las  distancias  de  cada  tramo,  así  como  la  distancia  total  a  recorrer  en  kms.  


• •

Encontrar las   rutas   más   cortas   desde   una   ciudad   origen   a   todas   las   demás   ciudades,   indicando  las  distancias  en  kms.   Dada   una   ciudad   de   origen   y   dos   ciudades   destino,   determinar   cuál   de   ellas   se   encuentra  más  cerca  y  cuál  es  la  diferencia  en  kms  con  respecto  a  la  que  se  encuentra   más  lejos.   Encontrar  la  ruta  más  larga  entre  dos  ciudades,  indicando  la  distancia  en  kms.  

  Equipo  7.     Sea  n  el  número  de  tipos  de  monedas  distintos,  L  la  cantidad  a  conseguir  y  T[1..n]  un  vector   con   el   valor   de   cada   tipo   de   moneda   del   sistema.   Supondremos   que   disponemos   de   una   cantidad  inagotable  de  monedas  de  cada  tipo.  Llamaremos  C(i,j)  (1  ≤  i  ≤  n,  1  ≤  j  ≤  L)  al  número   mínimo   de   monedas   para   obtener   la   cantidad   j  restringiéndose   a   los   tipos   T[1],   T[2],   ...,   T[i].   Si   no  se  puede  conseguir  dicha  cantidad  entonces  C(i,j)  =  ∞.  En  primer  lugar  hemos  de  encontrar   una   expresión   recursiva   de   C(i,j).   Para   ello   observemos   que   en   cada   paso   existen   dos   opciones:   1. No   incluir   ninguna   moneda   del   tipo   T(i).   Esto   supone   que   el   valor   de   C(i,j)   va   a   coincidir  con  el  de  C(i–1,j),  y  por  tanto  C(i,j)  =  C(i–1,j).   2. Sí   incluirla.   Pero   entonces,   al   incluir   la   moneda   del   tipo   T(i),   el   número   de   monedas   global   coincide   con   el   número   óptimo   de   monedas   para   una   cantidad   (j   –   T(i))   más   esta   moneda   T(i)   que   se   incluye,   es   decir   podemos   expresar   C(i,j)   en   este   caso   como   C(i,j)  =  1  +  C(i,j  –  T(i)).   El  cálculo  de  C(i,j)  óptimo  tomará  la  solución  más  favorable,  es  decir,  el  menor  valor  de  ambas   opciones.  Con  esto,  la  relación  en  recurrencia  queda  definida  como:  

  Una   vez   disponemos   de   la   solución   recursiva   del   problema,   aplicaremos   un   algoritmo   para   calcular  los  C(n,j),  1  ≤  j  ≤  L,  mediante  el  uso  de  un  vector  de  longitud  L.    

Trabajos finales de la materia g3