Está en la página 1de 9

Estado Plurinacional de Bolivia

Olimpiada Cient ca Estudiantil


Olimipiada Boliviana de Inform atica

Ejemplo de Examen - Nivel 3 Indice


Un Poligono en un Circulo Auto-N umeros (auto-n umeros) Loter a de Fin de Semana Las paginas est an numeradas desde el 1 al 8. 1 3 6

24 de junio de 2011

Primera Olimpiada de Inform atica

Problema 1
Un Poligono en un Circulo
Considere un poligono de lados iguales inscrito en un circulo

Figura 1: Poligono inscrito en un circulo Dado el radio del c rculo y el numero de poligonos se pide hallar el area del proligono.

Entrada
La entrada de datos consiste en dos numeros que representan el radio y el numero de poligonos.

Salida
Muestre en una linea la supercie del poligono redondeando al tercer decimal. Ejemplo de entrada 2 2000 Ejemplo de salida 12.566

Problema
Para el dato de entrada siguiente escriba un programa que halle la respuesta. 10 3000

La respuesta que debes entregar es: 314.159

Primera Olimpiada de Inform atica

An alisis y Soluci on
La longitud de cada lado de cada poligon es siempre la misma y es igual al radio del circulo. Dividiendo por el numero de poligonos obtenemos el angulo que esta junto al centro del circulo. . Asi que el area del triangulo es Este angulo es 2n A=
r2 sin( 2n ) 2

Multiplicando por el numero de triangulos tenemos el area total.

Programa que resuelve el problema


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 / Problema : P o l i g o n o en c i r c u l o Lenguaje : ANSI C++ / #include < s t d i o . h> #include <math . h> int main ( ) { int R, N; double A; scanf ( % d , &R ) ; ; scanf ( % d , &N ) ; ; A= r r s i n ( 2 3 . 1 4 1 6 /N) /2 N p r i n t f ( %.3 f \ n , A) ; } return 0 ; }

Primera Olimpiada de Inform atica

Problema 2
Auto-N umeros (auto-n umeros)
En 1949 el matem atico Indio DR. Kaprekar descubri o una clase n umeros llamados self-numbers, auto-n umeros. Para alg un entero positivo n, dene a d(n) como n mas la suma de los d gitos de n. (La d signica digit-adition, termino elegido por Kaprekar). Poro ejemplo, d(75) = 75+7+5 = 87. Dado un entero positivo n que es un punto inicial, usted puede construir la secuencia creciente innita de enteros n, d(n), d(d(n)), d(d(d(n))), .... Por ejemplo, si empieza con 33, el siguiente es 33 + 3 + 3 = 39, el siguiente es 39 + 3 + 9 = 51, el siguiente es 51 + 5 + 1 = 57, y as , puede generar la siguiente secuencia: 33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ... El n umero n es llamado generador de d(n). En la anterior secuencia 33 es un generador de 39, 39 es un generador de 51, 51 es un generador de 57 y as sucesivamente. Algunos n umeros tienen m as de un generador, por ejemplo 101 tiene dos generadores, 91 y 100. Un n umero sin generadores es un self-number. Hay trece self-numbers menores a 100: 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, y 97.

Entrada
La entrada constite en un numero que representa el numero self-number que queremos hallar.

Salida
Escriba un programa que muestre el self-number solicitado Ejemplo de entrada 1 2 3 4 5 Ejemplo de salida 1 3 5 7 9

Problema
Para el dato de entrada siguiente escriba un programa que halle la respuesta. 9

La respuesta que debes entregar es: 64

Primera Olimpiada de Inform atica

An alisis y Soluci on
Repasemos, en el problema, lo que solicita es encontrar todos los n umero x para los cuales no exista un n talque d(n) = x. La soluci on a este problema se simplica cuando hacemos una peque na prueba. d(0) = 0, d(1) = 2, d(2) = 4, d(3) = 6, d(4) = 8, d(5) = 10, d(6) = 12, d(7) = 14, d(8) = 16, d(9) = 18, d(10) = 11, d(11) = 13, d(12) = 15, d(13) = 17, d(14) = 19yd(15) = 21, bien, hasta este momento (n = 15), ya tenemos algunos self-numbers, pero para que sea m as claro distinguirlos usaremos un vector, que, inicialmente tendr a a todos sus valores iguales a 1 (que para nosotros signicar a 1 = es self number). Conforme vallamos calculando los valores de d(n), iremos poniendo a nuestro vector V [d(n)] = 0, donde 0 signicar a no es self-number, si hacemos este proceso para los n umeros del 1 al 15 tendremos el siguiente resultado: 1 1 1 1 1 1 | 1 1 1 1 2 2 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | 6 7 8 9 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 | 0 0 0 0 1 0 Como puede ver, ya tenemos la seguridad que desde el 1 al 15 existen los siguientes self-numbers: 1, 3, 5, 7 y 9. Note que, no podemos asegurar que hasta este momento que 20 es un self-number, puesto que no tenemos la seguridad de que entre d(16) hasta d(19) alguno de estos genere o no al n umero 20, por lo que no lo consideramos hasta que lleguemos a procesar dicho rango. Bien, como necesitamos encontrar los self-numbers del 1 al 10000, es l ogico suponer que tendremos que procesar hasta d(9999), comod(9999) = 10035, sabemos ahora que nuestro vector debe tener como m nimo 10035 elementos, caso contrario corremos el riesgo de desbordar la memoria y obtener un error en tiempo de ejecuci on. Ahora, para facilitarnos un poco la codicaci on, creemos una funci on que haga la adici on de d gitos (d()). int d(int n) { int s = n; while( n>0 ) { s += n%10; n /= 10; } return s; } Es una funci on b asica que se utiliza casi siempre en lo que es la introducci on a la programaci on. Cuando, declaramos un vector en Java, este es autom aticamente inicializado con los valores por defecto, (para el caso de un vector de booleans, lo inicializar a con valores false), pero en C y C++ ese no es el caso, por lo que tendremos que hacer la inicializaci on nosotros. for( i=0; i<MAX; i++) V[i] = 1; Luego haremos el siguiente recorrido for( i=0; i<MAX; i++) V[ d(i) ] = 0;

Primera Olimpiada de Inform atica

Con esto, ya tenemos identicados a todos los self-numbers del 1 hasta MAX, ahora solo tenemos que desplegar a aquellas posiciones que tengan el valor 1 como dato.

Programa que resuelve el problema


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 / Problema : AutoNumeros ( S e l t Numbers ) Lenguaje : ANSI C Por : A l b e r t o Suxo Nota : pre c a l c u l a r / #include < s t d i o . h> #define MAX 10000 int d ( int n ) { int s = n ; while ( n>0 ) { s += n % 1 0 ; n /= 1 0 ; } return s ; } int main ( ) { unsigned char V[ MAX+40 ] ; int i , n ; scanf ( % d ,&n ) ; f or ( i =0; i < MAX; i++ ) V[ i ] = 1 ; f or ( i =0; i < MAX; i++ ) V[ d ( i ) ] = 0 ; f or ( i =0; i < MAX; i++ ) i f ( V[ i ] && i==n ) printf ( % d \ n , i ) ; return 0 ; }

Primera Olimpiada de Inform atica

Problema 3
Loter a de Fin de Semana
Algunas personas est an contra loter as por razones morales, algunos gobiernos proh ben este tipo de juegos, pero con la aparici on del Internet esta forma de juego popular va prosperando, que comenz o en China y ayudo nanciar la Gran Muralla. Las probabilidades de ganar una loter a nacional se dan, y por lo tanto sus compa neros de clase de colegio decidieron organizar una peque na loter a privada, con el sorteo cada viernes. La loter a est a basada en un estilo popular: un estudiante que quiere apostar escoge C n umeros distintos de 1 a K y paga 1.00 Bs. (Las loter as tradicionales como la loter a estadounidense utilizan C = 6 y K = 49). El viernes durante el almuerzo C n umeros (de 1 a K ) son extra dos. El estudiante cuya apuesta tiene el n umero m as grande de aciertos recibe la cantidad de las apuestas. Esta cantidad es compartida en caso de empate y se acumulad a la pr oxima semana si nadie adivina cualquiera de los n umeros extra dos. Algunos de sus colegas no creen en las leyes de probabilidad y desean que usted escriba un programa que determine los n umeros a escoger, considerando los n umeros que menos salieron en sorteos anteriores, de modo que ellos puedan apostar a aquellos n umeros.

Entrada
La entrada contiene varios casos de prueba. La primera l nea de un caso de prueba contiene tres n umeros enteros N, C y K que indican, respectivamente, el n umero de sorteos que ya han pasado (1 N 10000), cuantos n umeros comprenden una apuesta (1 C 10) y el valor m aximo de los n umeros que pueden ser escogidos en una apuesta (C < K 100). Cada una de las N l neas siguientes contiene C n umeros enteros distintos Xi que indica los n umeros extra dos en cada sorteo anterior (1 Xi K ; para 1 i C ).

Salida
Para cada caso de prueba en la entrada su programa debe escribir una l nea de salida, conteniendo el juego de n umeros que han sido han salido la menor cantidad de veces. Este juego debe ser impreso como una lista, en orden creciente de n umeros. Inserte un espacio en blanco entre dos n umeros consecutivos en la lista.

Primera Olimpiada de Inform atica

Ejemplo de entrada 4 3 2 4 1 0 3 2 1 3 4 0 4 1 4 2 3 0

Ejemplo de salida 1 2 3 4

Problema
Para el dato de entrada siguiente escriba un programa que halle la respuesta. 5 6 3 2 4 2 4 2 4 3 5 3 6 3 6 6 2 6

4 5 5 6 4

La respuesta que debes entregar es: 1

An alisis y Soluci on
Si revisamos el problema vemos que lo se pide es hallar la frecuencia de los valores que vienen en el archivo. En el ejemplo la entrada 5 4 6 indica que han existido 5 sorteos, lo que implica leer 5 datos, el numero m aximo de estos es 6, y en cada apuesta hay cuatro n umeros. Esto signica leer 5 las de cuatro n umeros. Al leer contamos cuantas veces ha salido cada n umero y luego se imprimen los n umeros menores al n umero que haya salido menos veces. Para realizar esta cuenta se puede utilizar el siguiente c odigo cin >> x; count[x] + +;

Programa que resuelve el problema


1 / Problema : L o t e r i a de Fin de Semana 2 Lenguaje : C++ 3 Por : A l b e r t o Suxo 4 / 5 #include <i o s t r e a m >

Primera Olimpiada de Inform atica

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

#define MAX N 10000 #define MAX K 100 u s i n g namespace s t d ; int main ( ) { int n = 1 , c , k ; int i , j , x , min ; b o o l sw ; int count [MAX K + 1 ] ; while ( t r u e ) { c i n >> n >> c >> k ; i f ( n == 0 && c == 0 && k == 0 ) break ; / l i m p i a r e l v e c t o r count / f or ( i = 0 ; i <= MAX K; i ++) count [ i ] = 0 ; f or ( i = 0 ; i < n ; i ++) { f or ( j = 0 ; j < c ; j ++) { c i n >> x ; count [ x]++; } } min = n ; f or ( i = 1 ; i <= k ; i ++) i f ( count [ i ] < min ) min = count [ i ] ; sw = f a l s e ; f or ( i = 1 ; i <= k ; i ++) { i f ( count [ i ] == min ) { i f ( sw ) c o u t << ; sw = t r u e ; c o u t << i ; } } c o u t << e n d l ; } return 0 ; }

También podría gustarte