java soluciones

104
PROBLEMAS RESUELTOS Jorge Terán Pomier Docente de programación [email protected] Alberto Suxo Riveros Docente de programación [email protected] [email protected] La Paz – Bolivia, Noviembre 2007

Upload: chrismeza21

Post on 26-Nov-2015

68 views

Category:

Documents


6 download

TRANSCRIPT

  • PROBLEMAS RESUELTOS

    Jorge Tern PomierDocente de programacin

    [email protected]

    Alberto Suxo RiverosDocente de [email protected]

    [email protected]

    La Paz Bolivia, Noviembre 2007

  • PROBLEMAS RESUELTOS

    ii

  • PROBLEMAS RESUELTOS

    i

    IndiceVarios

    Impares o Pares .......................................................1Analizando el problema ........................................2Implementando una solucin ................................3

    Lotera de fin de semana ..........................................4Analizando el problema ........................................5Implementando una solucin ................................6

    Bubble Mapas...........................................................8Analizando el problema ......................................10Implementando una solucin ..............................11Solucin 2. .........................................................15

    Nmeros Romanos.................................................20Solucin: ............................................................21

    Cara o Cruz ............................................................24Solucin .............................................................25

    CadenasFcil De Decir?.....................................................27

    Solucin .............................................................28

    DespliegueInstruens Fabulam..................................................34

    Solucin .............................................................36

    SimulacinColorville.................................................................41

    Solucin .............................................................43

    EstructurasFalling Leaves ........................................................47

    Solucin: ............................................................49

    MathUna Funcin Inductivamente-Definida.....................54

    Solucin .............................................................55Raz Digital Prima...................................................58

    Solucin .............................................................60El Hotel con Habitaciones Infinitas ..........................64

    Solucin .............................................................65Regreso a la Fsica de Secundaria..........................67

    Solucin .............................................................67

  • PROBLEMAS RESUELTOS

    ii

    Un Problema Fcil! ................................................69Solucin .............................................................70

    Diagonales .............................................................72Solucin .............................................................73

    Nmeros Casi Primos.............................................77Solucin: ............................................................77

    BackTrackingEl Juego de Tringulos ...........................................81

    Solucin .............................................................82

    GrafosLa Rana Saltadora..................................................87

    Analizando el problema ......................................89Implementando una solucin ..............................90

    Encontrando al Prof. Miguel ... ................................95Solucin .............................................................97

  • PROBLEMAS RESUELTOS

    1

    Impares o ParesTipos de archivos aceptados: odd.c, odd.cpp, odd.java

    Existen Muchas versiones de pares impares, un juego qumuchos competidores realizan para decidir muchas cosas,por ejemplo, quien resolver este problema. En unavariacin de este juego los competidores comienzanescogiendo ya sea pares impares. Despus a la cuentade tres extiende una mano mostrando un nmero de dedosque pueden ser de cero hasta cinco. Luego se suman lacantidad escogida por los competidores. Si suma par lapersona que escogi par gana. Similarmente ocurre lomismo con la persona qu escoge impar, si suma impargana.

    Juan y Miara jugaron muchos juegos durante el da. Encada juego Juan escogi pares (y en consecuencia Miaraescogi impares). Durante los juegos se cada jugador anotoen unas tarjetas el numero de dedos que mostr. Miarautilizo tarjetas azules, y Juan tarjetas rojas. El objetivo era elde revisar los resultados posteriormente. Sin embargo alfinal del da Juan hizo caer todas las tarjetas. An cuandose podan separar por colores no podan ser colocadas enorden original.

    Dado un conjunto de nmeros escritos en tarjetas rojas yazules, usted debe escribir un programa para determinar elmnimo de juegos que Miara con certeza gano.

    InputLa entrada consiste de varios casos de prueba. La primeralnea de la prueba consiste en un entero N que representael numero de juegos (1 ? N ? 100). La segunda lnea es uncaso de prueba que contiene N enteros Xi, Indicando elnumero de dedos que mostr Miara en cada uno de losjuegos (0 ? Xi?? 5, para 1 ? i ? N). La tercera lnea contieneN enteros Yi, el nmero de dedos que escogi Juan en cadajuego. (0 ? Yi?? 5, para 1 ? i ? N). El fin de archivo se indicacon N = 0.

    La entrada se debe leer de standard input (teclado).

  • PROBLEMAS RESUELTOS

    2

    OutputPara cada caso de prueba su programa debe escribir enuna lnea un numero de entero, indicando el m minonmero de juegos que pudo haber ganado Miara.

    La salida debe ser standard output (pantalla).

    Ejemplo de Entrada31 0 43 1 290 2 2 4 2 1 2 0 41 2 3 4 5 0 1 2 30

    Salida para el ejemplo de Entrada03

    Analizando el problema

    Analicemos el primer ejemplo. Aqu Miara escogi 1, 0,4 y Juan 3, 1, 2. Analizando todas las posibilidades vemosque estas son tres

    Miara Juan Sumapar par parpar impar impar

    impar par imparimpar impar par

    Veamos, todo nmero par puede escribirse como 2n ytodo numero impar como 2n + 1, de donde se puedefcilmente deducir la tabla anterior.

    Si analizamos cuantos impares escogi Miara, se veque es solo el numero 1. La nica posibilidad de ganar seriacuando Juan escogi par o sea 2. En el caso de que Miarahubiese escogido par o sea 0 o 4 solo podra ganar cuandoJuan escogi 1.

  • PROBLEMAS RESUELTOS

    3

    Contando los casos tenemos: Pares Impares

    Miara 2 1Juan 1 2

    El mnimo nmero de juegos que Miara podra ganar es1 1.

    Implementando una solucin

    La solucin completa del problema es la siguiente:import java.io.*;import java.util.*;public class Odds {

    /*** J. Teran requieres jdk 1.5*/public static void main(String[] args) {

    int Juan = 0, Maria = 0, x, n, i; Scanner in = new Scanner(System.in);

    while ((n = in.nextInt()) > 0) { Juan = 0; Maria = 0;

    for (i = 0; i < n; i++) { x = in.nextInt();

    if ((x & 1) == 1) Maria++; }

    for (i = 0; i < n; i++) { x = in.nextInt();

    if ((x & 1) == 0) Juan++; } }

    if ( Juan > Maria ) System.out.println(Juan ? Maria);

    else System.out.println(Maria - Juan); }}

  • PROBLEMAS RESUELTOS

    4

    Lotera de fin de semanaTipos de archivos aceptados: lottery.c, lottery.cpp,

    lottery.javaAlgunas personas estn contra loteras por razonesmorales, algunos gobiernos prohben ste tipo de juegos,pero con la aparicin del Internet esta forma de juegopopular va prosperando, que comenz en China y ayudofinanciar la "Gran Muralla".

    Las probabilidades de ganar una lotera nacional se dan, ypor lo tanto sus compaeros de clase de colegio decidieronorganizar una pequea lotera privada, con el sorteo cadaviernes. La lotera est basada en un estilo popular: unestudiante que quiere apostar escoge C nmeros distintosde 1 a K y paga 1.00 Bs. (Las loteras tradicionales como lalotera estadounidense utilizan C = 6 y K = 49).

    El viernes durante el almuerzo C nmeros (de 1 a K) sonextrados. El estudiante cuya apuesta tiene el nmero msgrande de aciertos recibe la cantidad de las apuestas. Estacantidad es compartida en caso de empate y se acumulad ala prxima semana si nadie adivina cualquiera de losnmeros extrados.

    Algunos de sus colegas no creen en las leyes deprobabilidad y desean que usted escriba un programa quedetermine los nmeros a escoger, considerando losnmeros que menos salieron en sorteos anteriores, demodo que ellos puedan apostar a aquellos nmeros.

    EntradaLa entrada contiene varios casos de prueba. La primeralnea de un caso de prueba contiene tres nmeros enterosN, C y K que indica respectivamente el nmero de sorteosque ya han pasado (1 ? N ? 10000), cuantos nmeroscomprenden una apuesta (1 ? C ? 10) y el valor mximo delos nmeros que pueden ser escogidos en una apuesta (C 0) {

    c = in.nextInt(); k = in.nextInt(); count = new int[MAX_K + 1];

    for (i = 0; i < n; i++) {for (j = 0; j < c; j++) {

    x = in.nextInt(); count[x]++; } } min = n;

  • PROBLEMAS RESUELTOS

    7

    for (i = 1; i

  • PROBLEMAS RESUELTOS

    8

    Bubble MapasTipos de archivos aceptados: maps.c, maps.cpp, maps.java

    Bubble Inc Esta desarrollando una nueva tecnologa pararecorrer un mapa en diferentes niveles de zoom. Sutecnologa asume que la regin m se mapea a una reginrectangular plana y se divide en sub-regiones rectangularesque representan los niveles de zoom.

    La tecnologa de Bubble Inc. representa mapas utilizando laestructura conocida como quad-tree.

    En un quad-tree, una regio rectangular llamada x puede serdividida a la mitad, tanto horizontalmente como vertical-mente resultando en cuatro sub regiones del mismotamao. Estas sub regiones se denominan regiones hijo dex, y se llaman xp para la superior izquierda, xq para lasuperior derecha, xr de abajo y a la derecha y xs para lasde abajo a la izquierda xc representa la concatenacin de lacadena x y carcter c = 'p', 'q', 'r' o 's'. Por ejemplo si laregin base mapeada se denomina m, las regiones hijo dem son de arriba y en el sentido del reloj: mp, mq, mr y ms,como se ilustra.

    mp mqms mr

    Cada sub regin puede ser subdividida. Por ejemplo laregin denominada ms puede ser sub dividida en mas subregiones msp, msq, msr y mss, como se ilustra.

    msp msqmss msr

    Como otro ejemplo la figura muestra el resultada de dividirlas sub regiones hijo de llamada msr.

    msrpp msrpq msrqp msrqqmsrps msrpr msrqs msrqrmsrsp msrsq msrrp msrrqmsrss msrsr msrrs msrrr

    Los nombres de la sub regiones tienen la misma longitud dedel nivel de zoom, dado que representan regiones del

  • PROBLEMAS RESUELTOS

    9

    mismo tamao. Las sub regiones en el mismo nivel dezoom que comparten un lado comn se dicen vecinos.Todo lo que esta fuera de la regin base m no se mapeapara cada nivel de zoom todas las sub regiones de m sonmapeadas.

    La tecnologa de mapas Bubble's le provee al usuarioprovee al usuario una forma de navegar de una sub regina una sub regin vecina en las direcciones arriba, abajo,izquierda y derecha. Su misin es la de ayudar a BubbleInc. a encontrar la sub regin vecina de una sub regindada. Esto es que dado el nombre de una sub reginrectangular usted debe determinar los nombres de suscuatro vecinos.

    EntradaLa entrada contiene varios casos de prueba. La primeralnea contiene un entero representando el nmero de casosde prueba. La Primera lnea contiene un entero N indicandoel nmero de casos de prueba. Cada una de las siguientesN lneas representan un caso de prueba conteniendo elnombre la regin Compuesta por C caracteres (2 ? C ?5000), la primera letra siempre es una letra 'm' seguida poruna de las siguientes 'p', 'q', 'r' o 's'.La entrada se debe leer de standard input (teclado).

    SalidaPara cada caso en la entrada su programa debe produciruna lnea de salida, que contiene los nombres de las cuatroregiones de una regin dada, en el orden de arriba abajoizquierda y derecha. Para vecinos que no esta en mapadebe escribir < none > en lugar de su nombre. Deje unalnea en blanco entre dos nombres consecutivos.La salida debe ser standard output(pantalla).

    Ejemplo de entrada2mrsprmps

    Ejemplo de salidamrspq mrssq mrsps mrsqsmpp msp mpr

  • PROBLEMAS RESUELTOS

    10

    Analizando el problemaPara analizar el problema realizaremos una expansin

    de los datos de de los ejemplos. Comencemos con mps. Laregin m se divide en p, q, r y s:

    mp mqms mr

    Cada regin a su vez se divide en cuatro regionesformando:

    mpp mpq mqp mqqmps mpr mqs mqrmsp msq mrp mrqmss msr mrs mrr

    Analizando la regin mps se ve claramente que tiene unvecino arriba mpp, abajo msp a la izquierda no tiene porqueesta fuera del rea, y a la derecha mpr, lo que produce larespuesta al ejemplo planteado. Por ejemplo la regin msqtiene cuatro vecinos.

    Para esbozar una solucin podemos desarrollar el casode buscar el vecino superior. Los casos cuando estamos enuna regin r o una regin s siempre se tiene un vecinosuperior dado que cada regin tiene cuatro partes de lascuales r y s estn abajo.

    En los otros casos que son los sectores p y q puede serque no tengan vecino arriba. Para esto debemos recorrer lacadena hacia atrs hasta llegar a una regin que tenga unvecino superior. Si llegamos al final de la cadena sin lograresto significa que no tiene un vecino.

    En el cdigo queda representado como:

    public static void Arriba(int i) {if (i == 0) {

    vecinos[0] = 1;return;

    }switch (vecinos[i]) {case 'p':

    Arriba(i - 1); vecinos[i] = 's';

  • PROBLEMAS RESUELTOS

    11

    break;case 'q':

    Arriba(i - 1); vecinos[i] = 'r';

    break;case 'r':

    vecinos[i] = 'q';break;

    case 's': vecinos[i] = 'p';

    break; } }

    Para poder trabajar la cadena de caracteres ledoscomo un vector se ha convertido esta a un vector decaracteres. Esto se hace

    m = in.nextLine(); vecinos = m.toCharArray();

    La lgica para las 3 regiones restantes es la misma.

    Implementando una solucinLa solucin completa del problema es la siguiente:

    import java.util.*;public class Maps {

    /*** J. Teran requieres jdk 1.5*/public static char[] vecinos = new

    char[5000];public static void main(String[] args) {

    int n, i, l, l1; String m; Scanner in = new Scanner(System.in); m = in.nextLine(); n = Integer.parseInt(m);

    for (i = 0; i < n; i++) { m = in.nextLine();

  • PROBLEMAS RESUELTOS

    12

    vecinos = m.toCharArray(); l1 = m.length() - 1; l = l1; Arriba(l);

    if (vecinos[0] == 1) System.out.print(" ");

    else { System.out.print(vecinos); System.out.print(" "); } l = l1; vecinos = m.toCharArray(); Abajo(l);

    if (vecinos[0] == 1) System.out.print(" ");

    else { System.out.print(vecinos); System.out.print(" "); } vecinos = m.toCharArray(); l = l1; Izquierda(l);

    if (vecinos[0] == 1) System.out.print(" ");

    else { System.out.print(vecinos); System.out.print(" "); } vecinos = m.toCharArray(); l = l1; l = l1; Derecha(l);

    if (vecinos[0] == 1) System.out.println("");

    else { System.out.println(vecinos); } } }

    public static void Arriba(int i) {if (i == 0) {

    vecinos[0] = 1;return;

    }

  • PROBLEMAS RESUELTOS

    13

    switch (vecinos[i]) {case 'p':

    Arriba(i - 1); vecinos[i] = 's';

    break;case 'q':

    Arriba(i - 1); vecinos[i] = 'r';

    break;case 'r':

    vecinos[i] = 'q';break;

    case 's': vecinos[i] = 'p';

    break; } }

    public static void Abajo(int i) {if (i == 0) {

    vecinos[0] = 1;return;

    }switch (vecinos[i]) {case 'p':

    vecinos[i] = 's';break;

    case 'q': vecinos[i] = 'r';

    break;case 'r':

    Abajo(i - 1); vecinos[i] = 'q';

    break;case 's':

    Abajo(i - 1); vecinos[i] = 'p';

    break; } }

    public static void Derecha(int i) {if (i == 0) {

    vecinos[0] = 1;return;

  • PROBLEMAS RESUELTOS

    14

    }switch (vecinos[i]) {case 'p':

    vecinos[i] = 'q';break;

    case 'q': Derecha(i - 1); vecinos[i] = 'p';

    break;case 'r':

    Derecha(i - 1); vecinos[i] = 's';

    break;case 's':

    vecinos[i] = 'r';break;

    } }

    public static void Izquierda(int i) {// System.out.print("i="+i);//System.out.println(vecinos);if (i == 0) {

    vecinos[0] = 1;return;

    }switch (vecinos[i]) {case 'p':

    Izquierda(i - 1); vecinos[i] = 'q';

    break;case 'q':

    vecinos[i] = 'p';break;

    case 'r': vecinos[i] = 's';

    break;case 's':

    Izquierda(i - 1); vecinos[i] = 'r';

    break; } }}

  • PROBLEMAS RESUELTOS

    15

    Ejercicios Al subir en uno el nivel del zoom, determinar a que regin

    pertenece. Determinar nmero de niveles de zoom con los que se

    llega a la regin. Escribir las regiones que son diagonales a la regin

    dada.

    Solucin 2.

    Analizando el Problema Para entender y resolver el problema es necesario

    poner nfasis en el primer prrafo del planteamiento delproblema. Este prrafo nos dice:

    Bubble Inc. Desarrolla una nueva solucin de mapeo.Asume que el rea es superficie plana, y ha logradorepresentarlo en rboles-cuadrangulares (rboles concuatro hojas).

    Teniendo una regin rectangular llamada x, podemosdividirla por la mitad horizontal y verticalmente obteniendocuatro sub-regiones rectangulares de igual tamao. Estassub-regiones son llamadas regiones hijas de x, y sonllamadas: xp para superior-izquierdo, xq para superior-derecho, xr para inferior-derecho y xs para inferior-izquierdo, donde xc representa la concatenacin de lacadena x con el carcter c=p, q, r o s. Por ejemplo, sitenemos una regin llamada prs, sus hijos sern prsp, prsq,prsr y prss.

    Qu es lo que nos pide?En base a una cadena (que empiece con p) debemos

    hallar (desplegar en pantalla) a sus vecinos superior,inferior, izquierdo y derecho respectivamente, en caso de noexistir vecino desplegar .

    Cmo lo haremos?Primero simular lo que esta en el planteamiento del

    problema, con esto podremos comprender mejor la solucinal problema.

    Tenemos un rea (regin) inicial llamada p.

  • PROBLEMAS RESUELTOS

    16

    La dividimos en cuatro sub-regiones de igual tamao:

    Y concatenamos con p, q, r y s en sentido de lasmanecillas del reloj respectivamente:

    El resultado es un rea (matriz) de 2x2.Volvemos a dividirlo en cuatro regiones iguales cada

    sub-regin:

  • PROBLEMAS RESUELTOS

    17

    Y concatenamos con p, q, r y s en sentido de lasmanecillas del reloj respectivamente:

    El resultado es una matriz de 4x4:

    Volvemos a realizar el proceso de divisin en cuatropartes iguales de cada sub-regin, concatenamos y elresultado es:

    El resultado es una matriz de 8x8.

    Con este ejemplo ya podemos sacar nuestras propiasconclusiones:

    1.- Si en tamao de la cadena es k, la matriz resultantetendr un tamao de 2k-1x2k-12.- las coordenadas de columna y fila se duplican por cadacarcter en la cadena.3.- Si mi cadena es pqsr sus coordenadas son columna101= 5 y fila 011 = 34.- Lgicamente, un proceso inverso puede transformarcoordenadas x, y (columna, fila) en una cadena (nombre desub-regin).

  • PROBLEMAS RESUELTOS

    18

    Ejemplo:En los casos de entrada se propone: mpps, en una de

    las imgenes podemos apreciar que sus coordenadas son(x, y) = (00,01)b = (0, 1) y sus vecinos tienen las siguientescoordenadas:arriba = (x, y-1) = (0, 0) =(00,00)b = mpppabajo = (x, y+1) = (0, 2) = (00,10)b = mpspizquierda = (x-1, y) = (-1, 1) = fuera de la matriz = derecha = (x+1, y) = (1, 1) = (01,01)b = mppr

    Y como resultado debemos desplegar:mppp mpsp mppr

    Asumo que no es necesaria mayor explicacin as queaqu va el cdigo fuente en Java:

    /* Problem : Bubble Maps * Language : JAVA (version: 1.5 ) * By : Alberto Suxo **************************/import java.util.Scanner;public class Maps {

    static int x, y, size;static void coordenadas(String cad) {

    int i; x = 0; y = 0;

    for (i = 0; i < size; i++) { x

  • PROBLEMAS RESUELTOS

    19

    static String cadena(int x, int y){char c[]={'p', 's', 'q', 'r'};int dim, xx=x, yy=y;int i;

    String resp=""; dim = 1=0; i--){

    resp = c[((xx&1)= 1; yy >>= 1; }

    return "m" + resp; }

    public static void main(String args[]) {int n;

    String cad = null; Scanner in = new Scanner( System.in ); n = in.nextInt();

    while ( 0 < n-- ) { cad = in.next(); size = cad.length(); coordenadas( cad ); System.out.println(cadena(x, y - 1) + " " + cadena(x, y + 1) + " " + cadena(x - 1, y) + " " + cadena(x + 1, y) ); } }}

  • PROBLEMAS RESUELTOS

    20

    Nmeros RomanosEscriba un programa que convierta un entero positivo en unnmero romano. Asuma que los nmeros a convertir sonmenores a 3500. Las reglas para construir un nmeroromano son las que siguen.

    En el sistema de nmeros romanos, i es el smbolo para 1,v para 5, x para 10, l para 50, c para 100, d para 500 y mpara 1000. Los smbolos con un valor grande usualmenteaparecen antes que los smbolos de temor valor. El valor deun nmero romano es, en general, la suma de los valoresde los smbolos. Por ejemplo, ii es 2, viii es 8. Sin embargo,si un smbolo de menor valor aparece antes de un smbolode mayor valor, el valor de los dos smbolos es la diferenciade los dos valores. Pro ejemplo, iv es 4, ix es 9, y lix es 59.Note que no hay cuatro smbolos consecutivos iguales. Porejemplo, iv, pero no iiii, es el nmero 4. Los nmerosromanos construidos de esta forma pueden no ser nicos.Por ejemplo, ambos mcmxc y mxm son validos para 1990.Aunque el nmero romano generado por su programa nodebe necesariamente ser el ms corto, nunca use vv para10, ll para 100, dd para 1000, o vvv para 15, etc.

    EntradaLa entrada consistir en una serie de lneas, cada lneaconteniendo un entero x. La entrada terminar cuando lalnea tenga un 0.

    SalidaPor cada nmero, imprima el nmero en decimal y en formaromana.

    Ejemplo de entrada381724199050

  • PROBLEMAS RESUELTOS

    21

    Ejemplo de Salida3 iii8 viii172 clxxii4 iv1990 mcmxc5 v

    Nota: La salida esta en este formato: 111123456789012 ...|-----||---- ...1990 mcmxc

    Solucin:

    El problema solicita traducir un nmero menor o igual a3500 a nmero romano.

    La solucin clsica es, dado un nmero N, hacer unbucle mientras N sea mayor a cero, y dentro de este bucletener un conjunto de ifs anidados preguntando si el nmeroN es mayor o igual a algn valor.

    Ejemplo: Para N en un rango entre 1 y 35 pues es elsiguiente cdigo.

    while( N>0 )if( N>=10 ){print X, N=N-10}else if( N=9 ){print IX, N=0} else if( N>=5 ){print V, N=N-5} else if( N=4 ){print IV, N=0} else {print I, N=N-1}

    Y esto mismo se puede hacer para el problemaplanteado.

    En lo personal (Alberto), me disgusta utilizar tantosif?s anidados, as que propongo la siguiente solucin queutiliza un solo if dentro del while. La clave de estealgoritmo est en que recorre un vector Vn en donde estn

  • PROBLEMAS RESUELTOS

    22

    almacenados los posibles valores de x (N en el ejemplo dearriba), en caso de ser x>=Vn[i] imprime la cadenacorrespondiente y decrementa x en Vn[i], caso contrario,incrementa la variable i para que apunte al siguienteelemento del vector Vn.

    Esta solucin puede ser planteada en clase parademostrar que siempre hay una forma ms fcil y rpida dehacer las cosas.

    Cdigo fuente en C y JAVA:/* Problem : Numeros Romanos * Language : ANSI C (version 4.0) * By : Alberto Suxo **************************/#includeint main(){

    int x, i;int Vn[13]={ 1000, 900, 500, 400,

    100, 90, 50, 40, 10, 9, 5, 4, 1 };

    char *Vc[13]={"m","cm","d","cd","c","xc","l","xl","x","ix","v","iv","i"};

    while( 1 ){ scanf( "%d", &x );

    if( x==0 )break;

    printf( "%-4d ", x); i = 0;

    while( x>0 ){if( x>=Vn[i] ){

    printf( "%s", Vc[i] ); x = x - Vn[i]; }

    else i++; } printf( "\n" ); }

    return 0;}

  • PROBLEMAS RESUELTOS

    23

    /* Problem : Numeros Romanos * Language : JAVA (version: 1.5 ) * By : Alberto Suxo **************************/

    import java.util.Scanner;public class A{

    public static void main(String args[]){int x, i;int Vn[]={ 1000, 900, 500, 400,

    100, 90, 50, 40, 10, 9, 5, 4, 1 }; String Vc[]={"m","cm","d","cd",

    "c","xc","l","xl", "x","ix","v","iv","i"}; Scanner in = new Scanner( System.in );

    while( true ){ x = in.nextInt();

    if( x==0 )break;

    System.out.printf( "%-4d ", x); i = 0;

    while( x>0 ){if( x>=Vn[i] ){

    System.out.print( Vc[i] ); x = x - Vn[i]; }

    else i++; } System.out.println(); } }}

  • PROBLEMAS RESUELTOS

    24

    Cara o CruzJohn y Mary han sido amigos desde la guardera. Desdeentonces, ellos han compartido una rutina juguetona: cadavez que ellos se renen ellos juegan cara o cruz con unamoneda, y quien gana tiene el privilegio de decidir que vana jugar durante el da. Mary siempre escoge cara, y Johnsiempre escoge cruz.

    Hoy en da ellos estn en la universidad, pero continansiendo buenos amigos. Siempre que ellos se encuentran,ellos todava juegan cara o cruz y el ganador decide qupelcula mirar, o qu restaurante para tomar la cena juntos,y as sucesivamente.

    Ayer Mary confi a John que ella tiene en su custodia unregistro de los resultados de cada juego desde que ellosempezaron, en la guardera. Vino como una sorpresa paraJohn! Pero puesto que John est estudiando informtica, ldecidi que era una oportunidad buena de mostrarle sushabilidades a Mary programando, escribiendo un programapara determinar el nmero de veces en que cada uno deellos gan el juego durante los aos.

    EntradaLa entrada contiene algunos casos de prueba. La primeralnea de un caso de prueba contiene un entero N indicandoel nmero de juegos jugados (1 ? N ? 10000). La siguientelnea contiene N enteros Ri, separados por un espacio,describiendo la lista de resultados. Si Ri=0 significa queMary gan el i-simo juego, si Ri=1 significa que John ganel i-simo juego (1 ? i ? N). El final de las entradas estindicado por N=0;La entrada debe leerse desde la entrada estndar.

    SalidaPara cada caso de prueba en la entrada tu programa debemostrar una lnea conteniendo la frase Mary won X timesand John won Y times, donde X?0 y Y?0.La salida debe escribirse en la salida estndar.

  • PROBLEMAS RESUELTOS

    25

    Ejemplo de entrada50 0 1 0 160 0 0 0 0 10

    Ejemplo de salidaMary won 3 times and John won 2 timesMary won 5 times and John won 1 times

    Solucin

    El problema consiste nicamente en contar cuantasveces gan Mary y Cuantas veces gan John. O sea, contarcuantos 0s y 1s hay.

    Ejemplo6

  • PROBLEMAS RESUELTOS

    26

    Mary++; } printf( "Mary won %d times and Johnwon %d times\n", Mary, John ); }

    return 0;}

    /* Problem : Cara o Cruz * Language : JAVA (version: 1.5 ) * By : Alberto Suxo **************************/

    import java.util.Scanner;public class F{

    public static void main(String args[]){int N, coin, John, Mary;int i;

    Scanner in = new Scanner( System.in );while( true ){

    N = in.nextInt();if( N==0 )

    break; John = Mary = 0;

    for( i=0; i

  • PROBLEMAS RESUELTOS

    27

    Fcil De Decir?Un password seguro es algo delicado. Los usuariosprefieren passwords que sean fciles de recordar (comoamigo), pero este password puede ser inseguro. Algunoslugares usan un generador randmico de passwords (comoxvtpzyo), pero los usuarios toman demasiado tiemporecordndolos y algunas veces lo escriben en una notapegada en su computador. Una solucin potencial esgenerar password pronunciables que sean relativamenteseguros pero fciles de recordar.

    FnordCom est desarrollando un generador de passwords.Su trabajo en el departamento de control de calidad esprobar el generador y asegurarse de que los passwordssean aceptables. Para ser aceptable, el password debesatisfacer estas tres reglas:

    1. Debe contener al menos una vocal.2. No debe tener tres vocales consecutivas o tres

    consonantes consecutivas.3. No debe tener dos ocurrencias consecutivas de la

    misma letra, excepto por ee o oo.

    (Para el propsito de este problema, las vocales son 'a', 'e','i', 'o', y 'u'; todas las dems letras son consonantes.) Noteque Estas reglas no son perfectas; habrn muchas palabrascomunes/pronunciables que no son aceptables.

    La entrada consiste en una o ms potenciales passwords,uno por lnea, seguidas por una lnea conteniendo unapalabra 'end' que seala el fin de la entrada. Cada passwordtiene como mnimo una y como mximo veinte letras delargo y esta formado por solo letras en minscula. Por cadapassword, despliegue si es o no aceptable, usando elformato mostrado en el ejemplo de salida.

    Ejemplo de entradaatvptoui

  • PROBLEMAS RESUELTOS

    28

    bontreszoggaxwiinqeephouctuhend

    Ejemplo de salida is acceptable. is not acceptable. is not acceptable. is not acceptable. is not acceptable. is not acceptable. is acceptable. is acceptable.

    Solucin

    Este problema presenta tres simples reglas que sedeben cumplir para que un password sea aceptable.

    Primero es necesario identificar si un carcter es vocalo no, para lo cual utilizo la siguiente funcin que pregunta siel carcter es una vocal, y devuelve 1 (true) por verdad y 0(false) por falso.int isVowel( char ch ){

    if( ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u' )

    return 1;return 0;

    }

    Tambin podemos utilizar la un MACRO para reemplazaresta funcin en C:#define isVowel( ch )(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u')

    El cdigo es representado como funcin para simplificarla comprensin de su traduccin en JAVA.

  • PROBLEMAS RESUELTOS

    29

    Ahora iremos validando cada una de las trescondiciones expuestas en el planteamiento del problema ensu respectivo orden.

    Debe contener al menos una vocal.- Basta con realizar unrecorrido por toda la cadena (word), en cuanto encontremosuna vocal se retorna 1 (true) y si se ha terminado de hacerel recorrido y no se ha encontrado ninguna vocalretornamos 0 (false).int rule_1(){

    int i;for( i=0; i

  • PROBLEMAS RESUELTOS

    30

    diferencia es que empieza en el segundo elemento de lacadena y no as en el primero.int rule_3(){

    int i;for( i=1; i

  • PROBLEMAS RESUELTOS

    31

    int rule_2(){int i, v=0, c=0;for( i=0; i

  • PROBLEMAS RESUELTOS

    32

    import java.util.Scanner;public class D{

    static char word[];static int len;static boolean isVowel( char ch ){

    if( ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u' )

    return true;return false;

    }

    static boolean rule_1(){for( int i=0; i

  • PROBLEMAS RESUELTOS

    33

    public static void main( String args[] ){ String line; Scanner in = new Scanner( System.in );

    while( true ){ line = in.next();

    if( line.equals("end") )break;

    word = line.toCharArray(); len = line.length();

    if(rule_1()&& rule_2() && rule_3()) System.out.println( " is acceptable." );

    else System.out.println( " is not acceptable." ); } }}

    Es posible hacerlo todo con una nica funcin?Claro, existen muchas formas de hacer las cosas.

    int rules_1_2_3(){int i, v=0, c=0, vocs=0;for( i=0; i

  • PROBLEMAS RESUELTOS

    34

    Instruens FabulamInstruens Fabulam es la manera de dibujar un cuadro (otabla) en idioma Latino. Esto es lo que debes hacer paraeste problema.

    La entrada consiste en una o ms descripciones de tablas,seguidas por una lnea cuyo primer carcter es *, queseala el final de la entrada. Cada descripcin empieza conuna lnea de encabezado que contiene uno o mscaracteres que definen el nmero y el alineamiento de delas columnas de la tabla. Los caracteres del encabezadoson que son las justificaciones izquierda, centraly derecha de cada columna. Despus del encabezado hayal menos dos y a lo sumo 21 lneas de datos que contienenlas entradas de cada fila. Cada lnea de datos consiste enuna o ms entradas (no vacas) separadas por unampersand (&), donde el nmero de entradas es igual alnmero de columnas definidas en el encabezado. Laprimera lnea contiene los ttulos de las columnas, y laslneas de datos restantes contienen las entradas del cuerpode la tabla. Los espacios pueden aparecer dentro de unaentrada, pero nunca al principio ni al final de la entrada. Loscaracteres '', '&', y '*' no aparecern en la entradaexcepto en los lugares indicados arriba.

    Por cada descripcin de tabla, despliegue la tabla usando elformato exacto mostrado en el ejemplo. Note que:

    El ancho total de la tabla no exceder los 79 caracteres(sin contar el fin-de-lnea).

    Los guiones ('-') son usados para dibujar lneashorizontales, no ('_'). El signo de arroba ('@') apareceen cada esquina. El signo de suma (+) aparece en unainterseccin entre la lnea que separa el ttulo y elcuerpo de la tabla.

    Las entradas de una columna estas separadas por elcarcter (|) por exactamente un espacio.

    Si una entrada centreada no es exactamente centreadaen una columna, el espacio extra debe ir a la derechade la entrada.

  • PROBLEMAS RESUELTOS

    35

    Ejemplo de entrada=>TITLE&VERSION&OPERATING SYSTEM&PRICESlug Farm&2.0&FreeBSD&49.99Figs of Doom&1.7&Linux&9.98Smiley Goes to Happy Town&11.0&Windows&129.25Wheelbarrow Motocross&1.0&BeOS&34.97>What is the answer?42

    Tweedledum&Tweedledee"Knock, knock."&"Who's there?""Boo."&"Boo who?""Don't cry, it's only me."&(groan)*

    Ejemplo de salida@-----------------------------------------------------------------@| TITLE | VERSION | OPERATING SYSTEM | PRICE ||---------------------------+---------+------------------+--------|| Slug Farm | 2.0 | FreeBSD | 49.99 || Figs of Doom | 1.7 | Linux | 9.98 || Smiley Goes to Happy Town | 11.0 | Windows | 129.25 || Wheelbarrow Motocross | 1.0 | BeOS | 34.97 |@-----------------------------------------------------------------@@---------------------@| What is the answer? ||---------------------|| 42 |@---------------------@@---------------------------------------------@| Tweedledum | Tweedledee ||----------------------------+----------------|| "Knock, knock." | "Who's there?" || "Boo." | "Boo who?" || "Don't cry, it's only me." | (groan) |@---------------------------------------------@

  • PROBLEMAS RESUELTOS

    36

    Solucin

    Este problema no requiere mayor explicacin, basta conver el ejemplo de entrada y salida para saber de que setrata, y claro, al leer el planteamiento del problema, se tienela seguridad que ste es un problema de formato de salida.

    Tambin nos aclara que el tamao de la tabla jamsexceder los 79 caracteres. Si todas nuestras columnastuvieran solo un caracter, entonces tendramos comomximo 20 columnas (en realidad 19).

    Y tambin sabemos que tendremos de 2 a 21 filas ennuestra tabla. As que, en conclusin, necesitamos unatabla de cadenas de 21 filas y 20 columnas para almacenarnuestros campos.

    Cdigo fuente en C y su traduccin en JAVA:/* Problem : Instruens Fabulam * Language : ANSI C (version: 4.0) * By : Alberto Suxo **************************/#include#includechar Mat[25][20][80], dir[100];int size[20], cols;void chars( char ch, int length ){

    int i;for( i=0; i

  • PROBLEMAS RESUELTOS

    37

    void printline( int row ){int le, ri, wrd, i;

    putchar( '|' );for( i=0; i

  • PROBLEMAS RESUELTOS

    38

    for(cad = strtok(line,"&"), col=0; cad != NULL; cad = strtok(NULL,"&" ),col++){ strcpy( Mat[row][col], cad ); sz = strlen( cad );

    if( sz > size[col] ) size[col] = sz; } row++; } print( '@', '-' ); printline( 0); print( '|', '+' );

    for( j=1; j

  • PROBLEMAS RESUELTOS

    39

    static void print( char ch1, char ch2 ){ System.out.print( ch1 );

    for(int i=0; i

  • PROBLEMAS RESUELTOS

    40

    dir = line; cols = line.length(); size = new int[cols]; row=0;

    while( true ){ line = in.nextLine(); ch = line.charAt(0);

    if( ch=='' || ch=='=' || ch=='*' )

    break; StringTokenizer st = new

    StringTokenizer(line,"&");for ( col=0; st.hasMoreTokens();

    col++) { cad = st.nextToken(); Mat[row][col] = cad; sz = cad.length();

    if (sz > size[col]) size[col] = sz; } row++; } print('@','-'); printline(0); print('|','+');

    for(j=1; j

  • PROBLEMAS RESUELTOS

    41

    ColorvilleUn simple juego de nios usa un tablero que es unasecuencia de cuadrados coloreados. Cada jugador tieneuna pieza de juego. Los jugadores alternan turnos, sacandocartas que tienen cada una uno o dos cuadradoscoloreados del mismo color. Los jugadores mueven supieza hacia adelante en el tablero hacia el siguientecuadrado que haga pareja con el color de la carta, o haciaadelante hasta el segundo cuadrado que haga pareja con elcolor de la carta que contiene dos cuadrados coloreados, ohacia adelante hasta el ltimo cuadrado en el tablero si nohay un cuadrado con el que emparejar siguiendo ladescripcin anterior. Un jugador gana si su pieza est en elltimo cuadrado del tablero. Es posible que no existaganador despus de sacar todas las cartas.

    En este problema los colores se representan las letrasmaysculas A-Z, a continuacin se presenta un ejemplo.

    Considere el siguiente deck de cartas: R, B, GG, Y, P, B, P,RR

    Para 3 jugadores, el juego procede como sigue:

    Jugador 1 saca R, se mueve al 1er cuadradoJugador 2 saca B, se mueve al 5to cuadradoJugador 3 saca GG, se mueve al 8vo cuadradoJugador 1 saca Y, se mueve al 2do cuadradoJugador 2 saca P, se mueve al 11vo cuadradoJugador 3 saca B, se mueve al 9no cuadradoJugador 1 saca P, se mueve al 4to cuadradoJugador 2 saca RR, Gano! (no hay R?s alfrente de esta pieza as que va hasta elltimo cuadrado).

    Usando la misma tabla y el mismo deck de cartas, pero con2 jugadores, el jugador 1 gana despus de 7 cartas. Con 4jugadores, no hay ganador despus de utilizar todas las 8cartas.

  • PROBLEMAS RESUELTOS

    42

    La entrada consiste en informacin de uno o ms juegos.Cada juego comienza con una lnea conteniendo el nmerode jugadores (1-4), el nmero de cuadrados en el tablero (1-79), y el nmero de cartas en el deck (1-200). Seguido poruna lnea de caracteres que representan los cuadradoscoloreados del tablero. Seguidos por las cartas en el deck,uno el cada lnea. Las Cartas pueden tener una letra o dosde las mismas letras. El final de la entrada esta sealadocon una lnea que tiene 0 para el nmero de jugadores losotros valores son indiferentes.

    Por cada juego, la salida es el jugador ganador y el nmerototal de cartas usadas, o el nmero de cartas en el deck,como se muestra en el ejemplo de salida. Siempre use elplural "cards".

    Ejemplo de entrada2 13 8RYGPBRYGBRPOPRBGGYPBPRR2 6 5RYGRYBRYYGGB3 9 6QQQQQQQQQQQQQQQQQ0 6 0

  • PROBLEMAS RESUELTOS

    43

    Ejemplo de salidaPlayer 1 won after 7 cards.Player 2 won after 4 cards.No player won after 6 cards.

    Solucin

    El primer prrafo del planteamiento del problemadescribe claramente en que consiste el mismo.

    Para quien no entendi en qu consiste este problema,bastar con ver mejor el ejemplo propuesto en el problema.

    Este es nuestro tablero, y al inicio se encuentrannuestros tres jugadores (P1, P2 y P3)

    Tambin sabemos que las cartas de nuestro decksaldrn en el siguiente orden: R, B, GG, Y, P, B, P, RR

    Simulemos el juego de manera grfica:Jugador 1 saca R, se mueve al 1er cuadrado

    Jugador 2 saca B, se mueve al 5to cuadrado

    Jugador 3 saca GG, se mueve al 8vo cuadrado

    Jugador 1 saca Y, se mueve al 2do cuadrado

    Jugador 2 saca P, se mueve al 11vo cuadrado

  • PROBLEMAS RESUELTOS

    44

    Jugador 3 saca B, se mueve al 9no cuadrado

    Jugador 1 saca P, se mueve al 4to cuadrado

    Jugador 2 saca RR, Gano! ( no mas hay R?sal frente de esta pieza as que va hasta elltimo cuadrado).

    Bueno, con la simulacin grfica del ejemplo delproblema ya se entiende todo perfectamente.

    Cdigo fuente en C y JAVA:

    /* Problem : Colorville * Language : ANSI C (version: 4.0) * By : Alberto Suxo **************************/

    #includechar board[100];int hasNext( int ps, char ch ){

    int i;for( i=ps+1; board[i]!='\0'; i++){

    if( board[i]==ch )return i;

    }return -1;

    }

    int main(){int players, size, cards;char card[5];int pos[4];int i, j, win, player;

  • PROBLEMAS RESUELTOS

    45

    while( 1 ){ scanf( "%d %d %d\n", &players, &size, &cards );

    if( players==0 )break;

    scanf( "%s", board ); win = 0; pos[0] = pos[1] = pos[2] = pos[3] =-1;

    for( i=0; i

  • PROBLEMAS RESUELTOS

    46

    int[] pos = new int[4];int i, j, player;boolean win;

    Scanner in = new Scanner( System.in );while( true ){

    players = in.nextInt(); size = in.nextInt(); cards = in.nextInt();

    if( players==0 )break;

    board = in.next(); win = false; pos[0] =pos[1] =pos[2] =pos[3] =-1;

    for( i=0; i

  • PROBLEMAS RESUELTOS

    47

    Falling Leaves

    La Figura 1 muestra la representacin grfica de un rbolbinario de letras. Lo familiarizados con los rboles binariospueden saltarse la definicin de rbol binario de letras,hojas de un rbol binario, y bsqueda en un rbol binario deletras, e ir directo al problema.

    Definicin.Un rbol binario de letras puede ser una de dos cosas:

    1. Puede estar vaca.2. Puede tener un nodo raz. Un nodo tiene una letra

    como dato y hace referencia a subrboles izquierdo yderecho. Los subrboles izquierdo y derecho sontambin rboles binarios de letras.

    En la representacin grfica de un rbol binario de letras:1. Un rbol vaco es omitido completamente.2. Cada nodo esta indicado por

    Su dato letra, Un segmento de lnea abajo a la izquierda hacia su

    subrbol izquierdo, si el subrbol izquierdo no estvaco,

    Un segmento de lnea abajo a la derecha hacia susubrbol derecho, si el subrbol derecho no estavaco.

    Una hoja en un rbol binario es un nodo donde ambossubrboles estn vacos. En el ejemplo en la Figura 1, tienecinco nodos con datos B, D, H, P, y Y.

  • PROBLEMAS RESUELTOS

    48

    El recorrido preorder de un rbol de letras satisface laspropiedades:

    1. Si el rbol esta vaco, entonces el recorrido preorderest vaco.

    2. Si el rbol no esta vaco, entonces el recorridopreorder consiste en lo siguiente, en orden: El dato del nodo raz, El recorrido preorder del subrbol izquierdo del

    nodo raz, El recorrido preorder del subrbol derecho del nodo

    raz.El recorrido preorder del rbol de la Figura 1 esKGCBDHQMPY.

    Un rbol como el de la Figura 1 es tambin un rbol binariode bsqueda de letras. Un rbol binario de bsqueda deletras es un rbol de letras en el cual cada nodo satisface:

    1. Los datos raz vienen despus en el alfabeto quetodos los datos en los nodos en el subrbolizquierdo.

    2. Los datos raz vienen antes en el alfabeto que todoslos datos en los nodos en el subrbol derecho.

    El problema:Considere la siguiente secuencia de operaciones en unrbol binario de bsqueda de letras:

    Borrar las hojas y listar los datos removidosRepetir este proceso hasta que el rbol este vaco.

    Empezando por el rbol de abajo a la izquierda, producimosla secuencia de rboles mostrados, y hasta que el rbol

    este vaco removiendo las hojas de datosBDHPYCMGQK

  • PROBLEMAS RESUELTOS

    49

    Tu problema es empezar con tales secuencias de lneas dehojas de un rbol binario de bsqueda de letras y desplegarel recorrido preorder del rbol.La entrada contiene uno o ms sets de datos. Cada set dedatos es una secuencia de uno o ms lneas con letrasmaysculas. Las lneas contienen las hojas removidas delrbol binario de bsqueda de la forma descritaanteriormente. Las letras en una lnea estn listados enorden alfabtico. Los sets de datos estn separados poruna lnea que contiene un asterisco (*). El ltimo set dedatos est seguido por un signo de dlar ($). No hayespacios en blanco ni lneas vacas en la entrada.

    Por cada set de datos de entrada, hay un nico rbol binariode bsqueda que puede ser producido con la secuencia dehojas. La salida es una lnea que contiene solo el recorridopreorder del rbol, sin blancos.

    Ejemplo de entradaBDHPYCMGQK*ACB$

    Ejemplo de salidaKGCBDHQMPYBAC

    Solucin:

    Este es un clsico problema de estructuras de datos(rboles), la mayor parte del problema se hace referencia alos rboles binarios ordenados de caracteres.

    En resumen, dado un rbol de caracteres ordenado, sevan retirando todas la hojas del mismo, este proceso serepite hasta terminar vaciando el rbol. La informacin que

  • PROBLEMAS RESUELTOS

    50

    se nos otorgar son los conjuntos de hojas que se vanretirando en el orden en que se van retirando.

    EjemploBDHPYCMGQK

    La salida de nuestro programa debe ser una cadenaque exprese el recorrido preorder del rbol

    Para esto es lgico pensar que debemos reconstruir elrbol, esta tarea es relativamente simple.

    Cmo?Pues el problema dice que es un rbol ordenado, as

    que lo que tenemos que hacer es leer todas las cadenas decada set de datos, empezando desde la ltima lnea haciala primera insertaremos las letras en nuestro rbol(insercin ordenada), y luego lo imprimimos en preorder.

    Demos un vistazo al cdigo que presento, debo aclararque no estoy utilizando un rbol de la forma correcta, enrealidad estoy utilizando un vector que simula ser un rbol.

    struct tree{char l, r;

    } T['Z'+1];Este vector T tiene 91 posiciones (T[0], T[1],.., T[64],

    T[65], ... ,T[90]), pero a mi solo me interesa las posicionesdesde 65 al 90 (T[65],... ,T[90]) = (T[A],... ,T[Z]), como sepuede ver, para mi, el dato (letra) es la posicin en elvector, como cada elemento de este vector es unaestructura que contiene dos caracteres l y r que representanleft (izquierdo) y right (derecho) respectivamente, y estoscaracteres apuntan a las posiciones de su subrbolizquierdo y derecho respectivamente, y en caso de noexistir un subrbol pues tendrn el valor 0 (que seranuestro NULL).

    void insert( char rt, char ch );

  • PROBLEMAS RESUELTOS

    51

    Esta funcin recursiva se encarga de insertar el carcterch en orden alfabtico ascendente, realizando un recorridoempezando por la raz rt, el algoritmo es bastanteespecfico, as que no es necesario explicarlo con mayordetenimiento.

    Ahora est la funcin find(), en esta funcin leemos deforma recursiva cada uno de los sets de datos, esta funcintermina su lectura recursiva cuando encuentra un * o $(en base a estos caracteres identifica si todava hay mssets de datos de entrada), luego identifica cul es la raz delrbol, y posteriormente va insertando todos los caracteresde las lneas ledas, (como es una funcin recursiva queprimero lee las lneas de entrada, pues queda claro queempieza a procesar dichas lneas empezando por la ltimahacia la primera). Adjunto comentarios por cada operacinque realiza, estos comentarios ayudarn a la comprensinde dicha funcin.

    void find(){char line[27];int i;

    gets( line );if( line[0]=='*' || line[0]=='$' ){

    /* Si termino el set de datos */ root = 0; /* an no existe raz */

    if( line[0]=='*' )/*Si termin con * hay ms sets */

    hasNext = 1; /* de datos.*/ }else{ find();

    if( root ){/* Si hay raz, inserta todos los datos

    de la lnea en el rbol con raz root */for( i=0; line[i]; i++ ){

    insert( root, line[i] ); } }else{ /* Si no hay raiz, la raiz serla letra de la ltima lnea */ root = line[0]; } }}

  • PROBLEMAS RESUELTOS

    52

    Por ltimo est la funcin print(), que se encarga de laimpresin en preorder.void print( char rt ){

    if( rt ){ putchar( rt ); print( T[rt].l ); print( T[rt].r ); }}

    Que mientras exista un subrbol imprimir su raz, susubrbol izquierdo y su subrbol derecho.

    Cdigo fuente en C:/* Problem : Falling Leaves * Language : ANSI C (version: 4.0) * By : Alberto Suxo **************************/

    #include#includechar ch;char root;int hasNext;struct tree{

    char l, r;} T['Z'+1];

    void insert( char rt, char ch ){if( ch

  • PROBLEMAS RESUELTOS

    53

    void find(){char line[27];int i;

    gets( line );if( line[0]=='*' || line[0]=='$' ){

    root = 0;if( line[0]=='*' )

    hasNext = 1; }else{ find();

    if( root ){for( i=0; line[i]; i++ ){

    insert( root, line[i] ); } }else{ root = line[0]; } }}

    void print( char rt ){if( rt ){

    putchar( rt ); print( T[rt].l ); print( T[rt].r ); }}

    int main(){do{

    memset( T, 0, sizeof( T ) ); hasNext = 0; find(); print( root ); printf( "\n" ); }while( hasNext );

    return 0;}

  • PROBLEMAS RESUELTOS

    54

    Una Funcin Inductivamente-Definida

    Considere la funcin f que esta inductivamente definidapara enteros positivos, como sigue:

    )3()1()()12()2()2()1(1)1(

    ++=+==

    nfnfnfnnf

    f

    Dado un valor entero positivo n (mayor o igual a 1),encontrar el valor de )(nf .

    EntradaLa entrada consiste en una secuencia en valores enterospositivos para n seguidos por -1. Los enteros sonprecedidos y/o seguidos por espacios en blanco (blancos,tabs, y fin de lneas).

    SalidaPor cada entero positivo n, desplegar el valor de n y el valorde )(nf . Use la forma mostrara en el ejemplo de salida, yponga lneas en blanco entre las salidas de cada valor n.

    Ejemplo de entrada2 53

    153-1

    Ejemplo de salidaf(2) = 1

    f(53) = 27

    f(153) = 77

  • PROBLEMAS RESUELTOS

    55

    Solucin

    Este problema se presenta como uno recursivo por lasiguiente funcin:

    )3()1()()12()2()2()1(1)1(

    ++=+==

    nfnfnfnnf

    f

    Realizando los cambios necesarios podremos compren-der mejor esta funcin.

    Empecemos con:2

    2 knkn == , reemplazndolo en (2)

    tendremos:2

    )( kkf =

    Y tambin con:2

    112 -==+ knkn , reemplazndolo

    en: (3) tendremos

    ++

    -=

    21

    21)( kfkfkf

    Por lo que nuestra funcin quedara traducida de lasiguiente forma:

    ++

    -

    =

    =

    impareskkfkf

    pareskkk

    kf

    21

    21

    2

    11)(

    Para resolver el problema basta con transcribir estafuncin recursiva.

    Cdigo fuente en C y JAVA:

    /* Problem : Una Funcion InductivamenteDefinida

  • PROBLEMAS RESUELTOS

    56

    * Language : ANSI C (version: 4.0 ) * By : Alberto Suxo **************************/

    #includeint f( int n ){

    if( n==1 )return 1;

    if( n%2==0 )return n/2;

    elsereturn f( (n-1)/2 ) + f( (n+1)/2 );

    }

    int main(){int n;while( 1 ){

    scanf( "%d", &n );if( n==-1 )

    break; printf( "f(%d) = %d\n\n", n, f( n ) ); }

    return 0;}

    /* Problem : Una Funcion InductivamenteDefinida * Language : JAVA (version: 1.5 ) * By : Alberto Suxo **************************/import java.util.Scanner;public class B{

    static int f( int n ){if( n==1 )

    return 1;if( n%2==0 )

    return n/2;else

    return f( (n-1)/2 ) + f( (n+1)/2 ); }

  • PROBLEMAS RESUELTOS

    57

    public static void main( String args[] ){int n;

    Scanner in = new Scanner( System.in );while( true ){

    n = in.nextInt();if( n==-1 )

    break; System.out.println( "f(" + n +

    ") = " + f( n ) ); System.out.println(); } }}

    Nota: despus de ejecutar el programa para un rango dedatos desde 0 hasta 1000 y verificando las salidas,podemos ver que la solucin tambin se logra con (n+1) div2.

    Es decir, remplacemos las siguientes lneas:En C: printf( "f(%d) = %d\n\n", n, f( n ) );Por:

    printf( "f(%d) = %d\n\n", n, (n+1)/2);

    En JAVA:System.out.println( "f(" + n + ") = "

    + f( n ) );Por:

    System.out.println( "f(" + n + ") = " + (int)((n+1)/2) );

    Que pasa cuando n es par o impar?Bueno, es una divisin entera, as que los decimales

    simplemente se truncan.

  • PROBLEMAS RESUELTOS

    58

    Raz Digital PrimaLa raz digital de un nmero es hallado adicionando todos lodgitos en un nmero. Si el nmero resultante tiene ms deun dgito, el proceso es repetido hasta temer un simpledgito.

    Tu trabajo en este problema es calcular una variacin de laraz digital una raz digital prima. El proceso de adicindescrito arriba para cuando solo queda un dgito, peropodemos para en el nmero original, o en cualquier nmerointermedio (formado por la adicin) que sea nmero primo.Si el proceso contina y el resultado es un dgito que no esprimo, entonces el nmero original no tiene raz digitalprima.

    Un entero mayo que uno es llamado nmero primo sitiene solo dos divisores, el uno y si mismo.

    Por ejemplo, los primeros seis primos son 2,3, 5, 7, 11, y 13.

    El nmero 6 tiene cuatro divisores: 6, 3, 2, y1. Por eso 6 no es primo.

    Advertencia: en nmero 1 no es primo.

    EJEMPLOS DE RAIZ DIGITAL PRIMA1 Este no es un nmero primo, as que 1 no tiene razdigital prima.3 Este es un nmero primo, as que la raz digitalprima de 3 es 3.4 Este no es un nmero primo, as que 4 no tiene razdigital prima.11 Este es un nmero primo, as que la raz digitalprima de 11 es 11.642 Este no es un nmero primo, as que sumando 6 +

    4 + 2 = 12. Este no es un nmero primo, as quesumando 1 + 2 = 3. Este si es un nmero primo, asque la raz digital prima de 642 es 3.

    128 Este no es un nmero primo, as que sumando 1 +2 + 8 = 11. Este es un nmero primo, as que la razdigital prima de 128 es 11.

    886 Este no es un nmero primo, as que sumando 8 +8 + 6 = 22. Este no es un nmero primo, as que

  • PROBLEMAS RESUELTOS

    59

    sumando 2 + 2 = 4. Este no es un nmero primo,as que 886 no tiene raz digital prima.

    EntradaLa entrada contendr un entero en cada lnea en el rangode 0 a 999999 inclusive. El fin de la entrada se indica con elvalor 0.

    SalidaSi el nmero ingresado tiene raz digital prima, entonces sedebe desplegar el valor original y el valor de la raz digitalprima, caso contrario se despliega el valor original seguidopor la palabra none, los valores deben estar alineados conuna justificacin derecha de 7 espacios, como se muestraen el ejemplo de salida.

    Ejemplo de entrada134116421288860

    Ejemplo de salida 1 none 3 3 4 none 11 11 642 3 128 11 886 none

    Nota: la salida tiene el siguiente formato: 111111123456789012345 4 none 642 3

  • PROBLEMAS RESUELTOS

    60

    Solucin

    Como la descripcin lo indica, el problema consiste enverificar si un nmero es primo, de no serlo, sumar todos losdgitos de dicho nmero y repetir el proceso hasta encontrarun primo o hasta que el nmero solo tenga un dgito.

    Como podemos ver, slo se requiere de dos funcionesque por lo general se utilizan en introduccin a laprogramacin, o sea, que este problema se clasifica dentrode los ms fciles.

    Pare resolver este problema solo necesitamos recordarcomo sumar los dgitos de un nmero, y cmo verificar si unnmero es primo o no.

    En la funcin int prime( long N ) veremos quehay una serie de condicionales, pues esta funcin parte delos siguientes principios:

    1. Un nmero menor a dos no es primo.2. El nico primo par es el dos.3. Cualquier otro par no es primo.4. Basta con encontrar un divisor de N entre 3 hasta

    N para asegurar que no es primo.

    En la funcin long SumDig( long Ns ); solo sesuman los dgitos del nmero Ns. Tambin se debe ter muyen cuenta que el resultado de SumDig ( X ) es igual a Xcuando X

  • PROBLEMAS RESUELTOS

    61

    int prime( long N ) {int i, root;if ( N0 ){

    pr = 0; N2 = N; pr = prime( N2 );

    while( N2>9 && !pr ){ N2 = SumDig ( N2 ); pr = prime ( N2 ); }

    if( pr ) printf( "%7ld %7ld\n", N, N2 );

    else printf( "%7ld none\n", N ); scanf( "%ld", &N ); }

    return 0;}

  • PROBLEMAS RESUELTOS

    62

    /* Problem : Raiz Digital Prima * Language : JAVA (version: 1.5 ) * By : Alberto Suxo **************************/import java.util.Scanner;public class E{

    static boolean prime( long N ) {int i, root;if ( N0 ){ pr = false; N2 = N; pr = prime( N2 );

    while( N2>9 && !pr ){ N2 = SumDig ( N2 ); pr = prime ( N2 ); }

  • PROBLEMAS RESUELTOS

    63

    if( pr ) System.out.printf(

    "%7d %7d\n", N, N2 );else

    System.out.printf("%7d none\n", N );

    N = in.nextLong(); } }}

  • PROBLEMAS RESUELTOS

    64

    El Hotel con Habitaciones InfinitasLa ciudad de HaluaRuti tiene un extrao hotel conhabitaciones infinitas. Los grupos que llegan a ese hotelsiguen las siguientes reglas:

    a) Al mismo tiempo, solo miembros de un grupo puedenrentar el hotel.

    b) Cada grupo llega en la maana de un da y salen alanochecer de otro da.

    c) Otro grupo llega en la maana siguiente despus deque un grupo ha abandonado el hotel.

    d) Una caracterstica muy importante de un grupo quellega es que tiene un miembro ms que el grupoanterior a menos que sea el primer grupo. Ustedtendr el nmero de miembros del grupo inicial.

    e) Un grupo con n miembros se queda por n das en elhotel. Por ejemplo, si un grupo de cuatro miembrosllega el 1ro de Agosto en la maana, este se ir delhotel el 4 de Agosto por la noche y el siguiente grupode cinco miembros llegar el 5 de Agosto en lamaana y se ir en 5 das y as sucesivamente.

    Dado un tamao de grupo inicial usted debe encontrar eltamao del grupo que se encuentra en el hotel en un daespecfico.

    EntradaLa entrada contiene nmeros enteros S (1 ? S?? 10000) y D(1 ? D < 1015) en cada lnea. S denota el tamao inicial delgrupo y D denota el da en para el cual debe encontrar eltamao del grupo que est en el hotel, D-simo da(empezando desde 1). Todos los enteros de entrada ysalida son menores a 1015. Un tamao de grupo S significaque en el primer da un grupo de S miembros lleg al hotel yse quedar por S das, entonces llegar un grupo de S + 1miembros de acuerdo a las reglas descritas previamente.

    SalidaPor cada lnea de entrada, imprima en una lnea el tamaodel grupo que esta en el hotel en el D-simo da.

  • PROBLEMAS RESUELTOS

    65

    Ejemplo de entrada1 63 103 14

    Ejemplo de salida356

    SolucinEl inciso e) es bastante explcito, utilicemos los

    siguientes ejemplos:3 10 => 53 14 => 6 10 14 | |3334444555556666667777777888888889

    Esta serie sigue la misma secuencia que la siguienteserie: 1223334444555556666667777777888888

    Para el segundo ejemplo: 3 14 => 6 donde S=3, D=14 yel resultado es k=6. Tenemos que 3+4+5 < D

  • PROBLEMAS RESUELTOS

    66

    [ ]21)1(2

    41

    --++ SSDk

    Tambin utilizaremos la funcin ceil( k ), que nosdevuelve el entero ms pequeo que no sea menor que k.

    Cdigo fuente en C y Java:

    /* Problem :Hotel con Habitaciones Infinitas * Language : ANSI C (version: 4.0 ) * By : Alberto Suxo **************************/#include#includeint main(){

    double S, D, k;while( scanf("%lf %lf", &S, &D ) !=EOF ){

    k = sqrt( 2.0*D+S*(S-1.0)+0.25 ) -0.5; printf( "%.0lf\n", ceil(k) ); }

    return 0;}/* Problem :Hotel con Habitaciones Infinitas * Language : JAVA (version: 1.5 ) * By : Alberto Suxo **************************/import java.util.Scanner;public class Hotel{

    public static void main( String args[] ){long S, D;double k;

    Scanner in = new Scanner( System.in );while( in.hasNext() ){

    S = in.nextLong(); D = in.nextLong(); k = Math.sqrt(2.0*D+S*(S-1.0)+0.25) -0.5; System.out.println((int)Math.ceil(k)); } }}

  • PROBLEMAS RESUELTOS

    67

    Regreso a la Fsica de SecundariaUna partcula tiene una velocidad y aceleracin inicial. Si lavelocidad despus de cierto tiempo es v, entonces cual esel desplazamiento en el doble del tiempo?

    EntradaLa entrada contendr dos enteros el cada lnea. Cada lneaes un set de entrada. Estos dos enteros denotan los valoresde v (?100 ? v ? 100) y t (0 ? t ? 200) (t es el tiempo que lapartcula tiene la velocidad v)

    SalidaPor cada lnea de entrada imprima un entero en una lneaque denote el desplazamiento en el doble del tiempo.

    Ejemplo de entrada0 05 12

    Ejemplo de salida0120

    Solucin

    Pues bien, este problema no requiere mayorexplicacin:

    El primer prrafo dice:Una particular tiene una velocidad y aceleracin inicial.

    Si la velocidad despus de cierto tiempo es v entonces cuales el desplazamiento en el doble de tiempo?.

    La frmula para el desplazamiento es:2

    0 21 tatvx +=

  • PROBLEMAS RESUELTOS

    68

    Pero como no tenemos la aceleracin asumimos quea=0, y como nos pide la distancia en el doble del tiempopues tendremos:

    tvx 2 0=Bueno, aqu va el cdigo fuente en C y JAVA:

    /* Problem : Regreso a Fisica de Secundaria * Language : ANSI C (versin: 4.0 ) * By : Alberto Suxo **************************/

    #includeint main(){

    long Vo, t;while( scanf( "%ld %ld", &Vo, &t )!=EOF )

    printf( "%ld\n", 2*Vo*t );return 0;

    }

    /* Problem : Regreso a Fisica de Secundaria * Language : JAVA (versin: 4.0 ) * By : Alberto Suxo **************************/

    import java.util.Scanner;public class B{

    public static void main( String args[] ){int Vo, t;

    Scanner in = new Scanner( System.in );while( in.hasNext() ){

    Vo = in.nextInt(); t = in.nextInt(); System.out.println( 2*Vo*t ); } }}

    Nota: No deberan existir distancias negativas, pero paraeste problema en particular, es valido cuando la distanciaresultante es negativa.

  • PROBLEMAS RESUELTOS

    69

    Un Problema Fcil!Has odo el hecho La base de todo nmero normal ennuestro sistema es 10?. Prosupuesto, Yo no hablo desistema numrico de Stern Brockot. Este problema no tienenada que ver con este hecho pero quiz tenga algunasimilitud.

    Debes determinar la base N para un nmero entero R ydebers garantizar que R es divisible por (N-1). Debesimprimir el menor valor posible para N. El rango de N es 2 ?N ? 62 y los smbolos para una base 62 son (0..9 y A..Z ya..z). Similarmente, los smbolo para una base 61 son ( 0..9y A..Z y a..y) as sucesivamente.

    EntradaCada lnea de la entrada contiene un entero (como sedefine en matemtica) en cualquier base (2..62). Debesdeterminar cual es la menor base posible que satisface lacondicin. No hay valores invlidos en la entrada. El tamaoms grande del archivo de entrada es de 32KB.

    SalidaSi un nmero en estas condiciones es imposible imprima lalnea such number is impossible!. Por cada lnea deentrada debe haber una sola lnea de salida. La salida debeestas en un sistema numrico decimal.

    Ejemplo de entrada35A

    Ejemplo de salida4611

  • PROBLEMAS RESUELTOS

    70

    Solucin

    El escritor del problema da por hecho lo siguiente:

    Un nmero R en base N es divisible por (N-1) si y solo si lasuma de sus dgitos es divisible por (N-1)

    Ejemplo:

    689306410 es mltiplo de 9 ( 765986 * 9 = 6893064) y lasuma de sus dgitos es tambin mltiplo de 9.(6+8+9+3+0+6+4=36).

    Una vez comprendido el hecho en el cual se apoya elproblema, pues es simple resolverlo.

    1. No nos importa si el nmero es positivo o negativo (+ o -)puesto que da lo mismo. (Ejemplo: 36 y -36 ambos sondivisibles entre 9)

    2. Sumamos todos los dgitos (en decimal) de nuestronmero R.

    3. Hallamos el valor del dgito ms alto (x)4. Verificamos si el resultado de suma es divisible por algn

    valor desde x hasta 62, de existir, imprimimos dichovalor, de no existir imprimimos "such number isimpossible!"

    Una consideracin importante es:

    El tamao ms grande del archivo de entrada puede serde 32KB, esto quiere decir que, el caso ms extremo seracuando el nmero R ocupara esos 32KB (32768 Bytes), esdecir, que tenga 32768 caracteres, y si los dgitos de estenmero fueran z (el dgito ms grande), esto significaraque tendramos 32768 zetas o 32768 valores 62, y sisumamos los dgitos la variable tendra que soportar 32768x 62 = 2031616

  • PROBLEMAS RESUELTOS

    71

    /* Problem : Un Problema Facil! * Language : ANSI C (versin: 4.0 ) * By : Alberto Suxo **************************/#include#includelong count( char ch ){

    if( isdigit(ch) )return ch-'0';

    if( isupper(ch) )return ch-'A'+10;

    if( islower(ch) )return ch-'a'+36;

    return 0;}

    int main(){char ch;long sum, d, big;while( scanf( "%c", &ch )==1 ){

    if( ch=='\n' )continue;

    sum = 0; big = 1;

    while( ch!='\n' ){ d = count( ch ); sum += d;

    if( d > big ) big = d; scanf( "%c", &ch ); }

    for( ; big

  • PROBLEMAS RESUELTOS

    72

    DiagonalesEl nmero de diagonales de un n-gon no es menor que N.Cul es me valor mnimo posible de n?

    EntradaLa entrada contiene menos de 1001 lneas de entrada.Cada lnea contiene un entero positivo N (N ? 1015) queindica el nmero mnimo posible de diagonales. La entradatermina con una lnea que contiene un cero. Esta lnea noser procesada.

    SalidaPor cada lnea de entrada produzca una lnea de salida, quecontenga un nmero de serie, y sea el valor mnimo posiblepara n (Nmero de lados).

    Ejemplo de entrada1010010000

    Ejemplo de salidaCase 1: 7Case 2: 16Case 3: 47

  • PROBLEMAS RESUELTOS

    73

    Solucin

    El primer prrafo dice:El nmero de diagonales de un n-gon no es menor que

    N. Cul es el mnimo valor posible de n?

    Primero aclara que N es mayor o igual que n ( N ? n ) yque en base a algn N, debemos encontrar n.

    Para resolver este problema hay tener en cuenta losiguiente:

    Para el pentgono (5-gon) Si suponemos que cadapunta es una persona, que las personas llegan una detrsde otra, y cada persona que llega saluda a los anteriores,entonces, la 1ra no saluda a nadie, la 2da saluda a 1persona, la 3ra saluda a 2 personas, la 4ta saluda a 3personas y la 5ta saluda a 4 personas, el total de saludos

    es 43210 ++++=N que es: 2)1( -

    =nnN

    , estaformula es vlida para todo n-gon.

    Pero como slo queremos las diagonales (interiores) decada figura, pues simplemente le restamos n.

    nnnN --=2

    )1( o si prefieren 2

    32 nnN -=

    Y ya tenemos la mitad del trabajo realizado.

  • PROBLEMAS RESUELTOS

    74

    La diagonales de las figuras son:n ( n-gon ) 5 6 7 8N ( Diagonales ) 5 9 14 44

    Esto lo debemos interpretar como:Para n = 6 ( 6-gon ) puede contener 6, 7, 8 y 9

    diagonales.Para n = 7 ( 7-gon ) puede contener 10, 11, 12, 13 y 14

    diagonales.Y as sucesivamente.

    Ahora despejemos nnnN 32 2 -=

    0232 =-- Nnn

    2893 Nn +=

    Pero como 389:0 >+>" NN y como n no puedeser negativo, entonces:

    2893 Nn ++=

    Pero esta frmula debe ser ligeramente modificada ( Npor N-1 ) para satisfacer nuestras necesidades, este cambioser claramente justificado en los resultados de la siguientetabla:

    N n2

    893 Nn ++= n-1 2)1(893 -++

    =N

    n

    5 5 5 5 4 4,70156212 46 6 5,27491722 5 5 5 57 6 5,53112887 5 5 5,27491722 58 6 5,77200187 5 5 5,53112887 59 6 6 6 5 5,77200187 510 7 6,21699057 6 6 6 611 7 6,42442890 6 6 6,21699057 612 7 6,62347538 6 6 6,42442890 613 7 6,81507291 6 6 6,62347538 614 7 7 6 6 6,81507291 615 8 7,17,890835 7 7 7 7

  • PROBLEMAS RESUELTOS

    75

    En la tabla en cada columna significa:Col 1: En nmero N con en cual debemos trabajar.Col 2: El valor de n que debemos encontrar.Col 3: El valor de n hallado con la formula.Col 4: El resultado de la Col 3 con los decimales truncados.Col 5: El valor de n-1Col 6: El resultado de n hallado con la frmula modificada(N por N-1 )Col 7: El resultado de la Col 6 con los decimales truncados.

    En las columnas 4 y 7 consideramos los resultados conlos decimales truncado, esto es justificable, puesto que enC, C++ y JAVA, cuando asignamos un valor punto flotante auna variable de tipo entero pues los decimales se truncan(no se redondean).

    Bien, podemos concluir que el resultado para esteproblema lo hallamos con la siguiente formula:

    12

    )1(893+

    -++=

    Nn

    Bueno, aqu va el cdigo fuente en C y JAVA:

    /* Problem : Diagonales * Language : ANSI C (version: 4.0) * By : Alberto Suxo **************************/#include#includeint main(){

    long long N, n;long C=1;while( 1 ){

    scanf("%lld", &N);if( !N )

    break; n = (3 + sqrt(9.0+8.0*(N-1)))/2; printf("Case %ld: %lld\n", C++, n+1); }

    return 0;}

  • PROBLEMAS RESUELTOS

    76

    /* Problem : Diagonales * Language : JAVA (version: 1.5) * By : Alberto Suxo **************************/

    import java.util.Scanner;public class D{

    public static void main( String args[] ){long N, n;long C=1;

    Scanner in = new Scanner( System.in );while( true ){

    N = in.nextLong();if( N==0 )

    break; n = (long)(3 + Math.sqrt(9.0+8.0*(N-1) ) )/2; System.out.println("Case "+ C +": "+ (n+1) ); C++; } }}

  • PROBLEMAS RESUELTOS

    77

    Nmeros Casi PrimosLos nmeros casi primos son nmero no-primos que sondivisibles por solo un nmero primo. En este problema tutrabajo es escribir un programa que encuentre la cantidadde nmero casi primos dentro de cierto rango.

    EntradaLa primera lnea de la entrada contiene un entero N (N ?600) que indica cuantos sets de datos siguen. Cada una delas siguientes N lneas es un set de entrada. Cada setcontiene dos nmero enteros low y high (0 < low? ? high max) ){

  • PROBLEMAS RESUELTOS

    84

    max = sum; } }else{

    for( i=1; i

  • PROBLEMAS RESUELTOS

    85

    import java.util.Scanner;public class A {

    static int max, k;static int P(int x) {

    return x % 3; }

    static int[][] T = new int[6][4];static void find( int dt, int lvl,

    int sum) {int i, j;if ( lvl == 6 ) {

    if ( (dt==T[0][k]) && (sum > max)){ max = sum; } } else {

    for ( i = 1; i < 6; i++ )if ( T[i][3] == 1 )

    for ( j = 0; j < 3; j++ )if ( dt == T[i][j] ) {

    T[i][3] = 0; find( T[i][P(j + 1)], lvl + 1, sum + T[i][P(j + 2)] ); T[i][3] = 1; } } }

    public static void main(String args[] ) { String ch;

    int i; Scanner in = new Scanner( System.in );

    do {for ( i = 0; i < 6; i++ ) {

    T[i][0] = in.nextInt(); T[i][1] = in.nextInt(); T[i][2] = in.nextInt(); T[i][3] = 1;

  • PROBLEMAS RESUELTOS

    86

    } ch = in.next(); max = -1;

    for ( k = 0; k < 3; k++ )/* Los tres posibles giros del

    primer triangulo */ find( T[0][P(k + 1)], 1, T[0][P(k + 2)] );

    if ( max < 0 ) System.out.println( "none" );

    else System.out.println( max ); } while ( ch.equals("*") ); }}

  • PROBLEMAS RESUELTOS

    87

    La Rana SaltadoraTipos de archivos aceptados: frog.c, frog.cpp, frog.java

    La rana vive en un pantano en forma de rejilla de formarectangular, compuesta de celdas de igual tamao, algunasde las cuales que son secas, y algunas que son lugares conagua. La Rana vive en una celda seca y puede saltar deuna celda seca a otra celda seca en sus paseos por elpantano.

    La rana desea visitar a su enamorado que vive en una celdaseca en el mismo pantano. Sin embargo la rana es un pocofloja y desea gastar el mnimo de energa en sus saltosrumbo a la casa de su cortejo. La Rana conoce cuantaenerga gasta en cada uno de sus saltos.

    Para cada salto, la rana siempre utiliza la siguiente figurapara determinar cuales son los posibles destinos desde lacelta donde esta (la celda marca con F), y lacorrespondiente energa en caloras gastada en el salto.

    Ninguna otra celda es alcanzable desde la posicincorriente de la rana con un solo salto.

    7 6 5 6 76 3 2 3 65 2 F 2 56 3 2 3 67 6 5 6 7

    Su tarea es la de determinar la cantidad de energa mnimaque la rana debe gastar para llegar de su casa a la casa desu enamorado.

    EntradaLa entrada contiene varios casos de prueba. La primeralnea de un caso de prueba contiene dos enteros, C y R,indicando el numero de columnas y filas del pantano (1 ?C;R ? 1000). La segunda lnea de los casos de pruebacontiene cuatro enteros Cf , Rf , Ct, y Rt, donde (Rf ;Cf )especifican la posicin de la casa de la rana y (Rt;Ct)especifican la casa de enamorada donde (1 ? Cf ;Ct?? C y 1? Rf ;Rt? ? R). La tercera lnea de los casos de pruebacontiene un numero entero W (0 ? W ? 1000) indicando los

  • PROBLEMAS RESUELTOS

    88

    lugares donde hay agua en el pantano. Cada una de lassiguientes W lneas contienen cuatro enteros C1, R1, C2, yR2 (1 ? C1?? C2?? C y 1 ? R1?? R2?? R) describiendo un lugaracuoso rectangular que abarca coordenadas de las celdascuyas coordenadas (x; y) son tales que C1?? x ? C2 y R1?? y? R2. El final de los datos se especifica con C = R = 0.

    La entrada se debe leer de standard input (teclado).

    SalidaPara cada caso de prueba en la entrada, su programa debeproducir una lnea de salida, conteniendo el mnimo decaloras consumidas por la rana para llegar desde su casa ala casa de su enamorada.Si no existe un camino su programa debe imprimirimpossible.

    La salida debe ser standard output (pantalla).

    Ejemplo de entrada4 41 1 4 222 1 3 34 3 4 44 41 1 4 212 1 3 47 64 2 7 654 1 7 15 1 5 52 4 3 47 5 7 56 6 6 60 0

    Ejemplo de salida14impossible12

  • PROBLEMAS RESUELTOS

    89

    Analizando el problemaTomemos como ejemplo el primer caso de los datos de

    ejemplo. Se indica que se tiene un pantano de 4 por 4 quequedara representado por la siguiente matriz:

    (1,1) (1,2) (1,3) (1,4)(2,1) (2,2) (2,3) (2,4)(3,1) (3,2) (3,3) (3,4)(4,1) (4,2) (4,3) (4,4)

    La segunda lnea indica los lugares de donde parte larana y a donde debe llegar que son las celdas (1,1) y (4,2).En nuestra matriz serian:

    origen (1,2) (1,3) (1,4)(2,1) (2,2) (2,3) destino(3,1) (3,2) (3,3) (3,4)(4,1) (4,2) (4,3) (4,4)

    Seguidamente se especifican dos regiones de agua laprimera (1,2) y (3,3) y la segunda (3,4) y (4,4). En nuestramatriz marcamos las regiones acuosas:

    origen 1- -1 (1,4)(2,1) -1 -1 destino(3,1) -1 -1 -1(4,1) (4,2) (4,3) -1

    Los posibles lugares donde se puede ir del origen con latabla de saltos son las celdas (1,2) y (1,3), dado que lasotras posiciones estn cubiertas de agua. De la posicin(1,2) se puede ir a las posiciones (1,3), (1,4) y (4,3).

    Continuando con todas las celdas podemos construir elsiguiente grafo que representa los posibles saltos de larana.

    Ahora se puede implementar una solucin pararesolver el problema. Este tipo de soluciones vienecaracterizado por el algoritmo de Dijkstra.

  • PROBLEMAS RESUELTOS

    90

    Implementando una solucinPara implementar una solucin primeramente es

    necesario definir una matriz que represente el grafo.Colocaremos en esta matriz las reas acuosas en -1 y en 1las reas secas.

    Como de la posicin actual de la rana se puede unomover dos lugares hacia arriba, abajo, izquierda y derechacrearemos una matriz con _las y columnas adicionales paraevitar controlar si estamos dentro o fuera del pantano. Estasfilas las representaremos con -2. El cdigo java para leer losdatos de entrada seria el siguiente:

    public static final int agua = -1;public static final int libre = 1;public static final int fueraPantano =-2;public static final int enteroMaximo =

    999999;public static final int energia[][] =

    { { 7, 6, 5, 6, 7 }, { 6, 3, 2, 3, 6 }, { 5, 2, 0, 2, 5 }, { 6, 3, 2, 3, 6 }, { 7, 6, 5, 6, 7 } };

    public static void main(String[] args) {int c = 0, r = 0, cs = 0, rs = 0;int ct = 0, rt = 0, b;int c1, r1, c2, r2;

  • PROBLEMAS RESUELTOS

    91

    int i, j, k;int[][] pantano = null;int[][] costo = null;

    Scanner in = new Scanner(System.in);// leer las dimensiones del pantano

    c = in.nextInt(); r = in.nextInt();

    while (c > 0) {// crear el pantano y matriz de costos

    pantano = new int[r + 4][c + 4]; costo = new int[r + 4][c + 4];

    // indicar que la fila 0 y columa 0// estan fuera del pantanofor (i = 0; i < c + 4; i++)

    pantano[0][i] = pantano[1][i] =fueraPantano;

    for (i = 0; i < r + 4; i++) pantano[i][0] = pantano[i][1] =fueraPantano;

    for (i = 2; i < c + 4; i++) pantano[r + 2][i] = pantano[r +3][i] = fueraPantano;

    for (i = 2; i < r + 4; i++) pantano[i][c + 2] = pantano[i][c+ 3] = fueraPantano;// Marcar las celdas del pantano como libres// y los costos como un entero grande

    for (i = 2; i < r + 2; i++) {for (j = 2; j < c + 2; j++) {

    pantano[i][j] = libre; costo[i][j] = enteroMaximo; } }

    // leer el origen y el destino cs = in.nextInt(); rs = in.nextInt(); ct = in.nextInt(); rt = in.nextInt();

    // leer el numero de zonas acuosas b = in.nextInt();

    for (i = 0; i < b; i++) {// leer las cordenadas de la region

    c1 = in.nextInt(); r1 = in.nextInt();

  • PROBLEMAS RESUELTOS

    92

    c2 = in.nextInt(); r2 = in.nextInt(); c1 += 1; c2 += 1; r1 += 1; r2 += 1;

    for (k = r1; k

  • PROBLEMAS RESUELTOS

    93

    Para el procesamiento del algoritmo de Dijkstra secomienza del origen y se ve a que lugares se puede ir, si semejora el costo se guarda en una estructura de datos y seanota en la matriz de costos, luego se toma un valor de losguardados y se repite el proceso.

    Codificando esto queda como sigue:public static void dijkstra(

    int[][] pantano, int[][] costo,int rs, int cs,int rt, int ct) {

    int rv, cv;int i, j;

    Nodo filcol; PriorityQueue cp =

    new PriorityQueue(); costo[rs][cs] = 0; rv = rs; cv = cs; cp.add(new Nodo(0, rs, cs));

    while (!cp.isEmpty()) { filcol = cp.remove(); rv = filcol.fila; cv = filcol.col;

    for (i = -2; i < 3; i++) {for (j = -2; j < 3; j++) {

    if(pantano[rv+i][cv+j]==libre) {if (costo[rv + i][cv + j] >

    (costo[rv][cv] + energia[i+2][j+2]) ) { costo[rv + i][cv + j] =costo[rv][cv] + energia[i + 2][j + 2]; cp.add(new Nodo(costo[rv +i][cv + j], rv + i, cv + j)); } } } } }}

    Ahora nos queda escoger una estructura de de datosapropiada. Siempre es deseable comenzar por el nodo quetenga el costo mnimo, dado que de esta forma es posibleque se reduzca el tiempo de proceso. Por esto considere

  • PROBLEMAS RESUELTOS

    94

    apropiado utilizar una estructura de cola de prioridad dondeuna vez insertados los valores se obtiene al extraer un valorel de menor costo.

    En java se implementa definiendo un objeto de clasePriorityQueue, en el programa se utilizo:

    PriorityQueue cp = newPriorityQueue();

    La clase nodo se defini como sigue:

    class Nodo implements Comparable {int costo, fila, col;public Nodo(int costo,int fila,int col) {

    this.costo = costo;this.fila = fila;this.col = col;

    }public int compareTo(Nodo other) {

    return costo - other.costo; }}Ejercicios1. Probar la solucin presentada con diferentes tipos deestructuras de datos, pilas, vector, etc.2. Modificar el programa para decir cuantos caminosdiferentes existen, que den el mismo recorrido mnimo.3. Modificar el programa para listar todos los recorridosmnimos.4. Hallar el camino de mximo esfuerzo.

  • PROBLEMAS RESUELTOS

    95

    Encontrando al Prof. Miguel ...Pienso que algn da podr encontrar al Profesor Miguel,quien me ha permitido organizar varios concursos. Pero enrealidad he fallado en todas mis oportunidades. En el ltimocon la ayuda de un mago he logrado encontrarme con l enla mgica Ciudad de la Esperanza. La ciudad de laesperanza tiene muchas calles. Algunas son bi-direccionales y otros son unidireccionales. Otracaracterstica importante de estas calles es que algunas sonpara personas menores de treinta aos, y el resto son paralos otros. Esto es para dar a los menores libertad en susactividades. Cada calle tiene un cierto tamao. Dada unadescripcin de tal ciudad y nuestras posiciones iniciales,debes encontrar el lugar ms adecuado donde nospodemos encontrar. El lugar ms apropiado es el lugar endonde nuestros esfuerzos para llegar combinados sea elmnimo. Debes asumir que yo tengo 25 aos y el Prof.Miguel mas de 40.

    Primer encuentro despus de cinco aosde colaboracin (Shanghai, 2005)

    EntradaLa entrada contiene varias descripciones de ciudades. Cadadescripcin de ciudad empieza con un entero N, el cualindica cuantas calles hay. Las siguientes N lneas tienen lasdescripciones de N calles. La descripcin de cada calleconsiste en cuatro letras maysculas y un entero. Laprimera letra puede ser Y (indica que es una calle para

  • PROBLEMAS RESUELTOS

    96

    jvenes young), o M (indica que es una calle para gentede 30 o mas aos). La segunda letra puede ser U (indicaque la calle es unidireccional) o B (indica que la calle esbidireccional). Las tercera y cuarta letras, X y Y (letrasmaysculas) indican los lugares llamados X y Y de la ciudadque son conectados (in caso de unidireccional significa quees de un solo sentido de x hacia Y) y el ltimo entero nonegativo C indica la energa requerida para caminar atravs de la calle. Si ambos estamos en el mismo lugar nosencontraremos uno al otro con cero de costo de todasformas. Cada valor de energa es menor que 500.

    Despus de la descripcin de la ciudad, la ltima lnea decada entrada contiene dos nombre de lugares, que son lasposiciones iniciales de mi y del Prof. Miguelrespectivamente.

    Un valor cero para N indica el fin de entrada.

    SalidaPor cada ser de entrada, imprima el mnimo costo deenerga y el lugar, que es ms adecuado para encontrarnos.Si hay ms de un lugar para encontrarnos imprima todos enorden lexicografito en la misma lnea, separados por unespacio en blanco. Si no existe tal lugar donde encontrarnosentonces imprima la lnea You will never meet.

    Ejemplo de Entrada4Y U A B 4Y U C A 1M U D B 6M B C D 2A D2Y U A B 10M U C D 20A D0

    Ejemplo de Salida10 BYou will never meet.

  • PROBLEMAS RESUELTOS

    97

    Solucin

    Encontrando al profesor Miguel es un clsico problemade recorrido de grafos, para resolver este problema youtilizar el algoritmo Floyd, (no es la nica forma, tambinpueden hacerlo de otra forma, ejemplo Dijkstra que seramucho ms rpido).

    En resumen, el problema consiste en encontrar el puntode reunin entre Shahriar (autor del problema) y el profesorMiguel que requiera del menor esfuerzo posible, en caso deexistir varios, pues desplegarlos en orden alfabtico, y porltimo, en caso de no existir dicho lugar pues imprimir Youwill never meet..

    La entrada del problema especifica si es un caminopara Shahriar o para Miguel, si es Unidireccional o bi-direccional, origen, destino y la energa requerida.

    Y luego, las calles en donde inician Shahriar y Miguel.

    La energa requerida es menor a 500, en el caso detener que ir de A a Z pasando por todas las dems letras, laenerga total seria de 500*25 que es 12500, cualquier valorsuperior a este ser nuestro INFINITO que en mi caso enparticular ser 16843009 que en binario es 0000000100000001 00000001 00000001, este valor es apropiadoporque yo utilizo la funcin memset( M, 1, sizeof(M) ), quellena todos los bytes de la matriz M con el valor 1.

    Utilizo dos MACROS:#define MIN(a,b) a

  • PROBLEMAS RESUELTOS

    98

    Despus de haber llenado la matriz con el valor deINFINITO, procedemos a llenar la matriz con los costos decada camino.

    for( i=0; i

  • PROBLEMAS RESUELTOS

    99

    apareciera un valor menor al INFINITO, es obvio que nuncase encuentran, de existir un valor menor, despliego enorden alfabtico todas las posiciones donde el resultado dela suma sea igual a dicho mnimo.

    A continuacin el cdigo fuente en C:

    /* Problem H: Meeting Prof. Miguel ... * Language : ANSI C (version: 4.0) * By : Alberto Suxo **************************/#include#include#define MIN(a,b) a

  • PROBLEMAS RESUELTOS

    100

    /*Algoritmo Floyd;*/for( k=0; k