Concurso Programacion

gF

Antes de entrar de lleno, una pequeña introducción para saber de que va la cosa:

Cada año se celebran las Olimpiadas de programación de la ACM (Association for Computing Machinery), las cuales designan a los mejores programadores universitarios del planeta. Para acceder a la fase final hay que pasar una fase regional española y luego una fase europea. De momento yo ya he pasado la fase regional de mi universidad y a final de año iré a Portugal a la fase europea.

Normalmente los problemas que ponen son mezcla de ingenio mezcla de implementar algún algoritmo conocido adaptándolo para el problema (Floyd-Washall, coloración de grafos, programación dinámica...).

Pues bien, para entrenar para la competición, tienen una página web con una gran cantidad de problemas de diferente tipo y un juez online que comprueba si el programa que escribas para un determinado problema es correcto o no.
Los lenguajes que se pueden utilizar para resolver problemas son C, C++, Pascal y Java. Yo recomiendo C o C++ ya que Java tiene bastantes limitaciones impuestas por la organización y el compilador de Java que usan creo que no acepta todas las versiones de Java, aunque de esto no estoy muy seguro.

Lo que propongo es cada semana elegir un problema y ver cuantos sois capaces de resolverlo. El enunciado de los programas está en inglés, así que más vale que tengáis un buen nivel de inglés.

INSTRUCCIONES PARA QUIEN QUIERA PARTICIPAR:

1º Registrarse en la web: http://acm.uva.es/problemset/registerjudge.php?acc=1

En el campo "Your Name & Surname" sugeriría que pusierais por ejemplo además de vuestro nombre el tag [MVida] para poder realizar búsquedas de los usuarios que se registren. MARCAR LA OPCION "You want to receive the replies from the Online Judge to: Always to the E-Mail address specified at the top" y poned un mail válido pq así el juez os mandara si un programa que escribais es correcto o no.

2º Una vez que CREAIS que vuestro programa resuelve un problema propuesto tendreis que entrar en esta página: http://acm.uva.es/problemset/submit.php y rellenar los datos (nº del programa, tu nº identificador que te darán al registrarte, seleccionar el lenguaje de programación elegido y enviar el código fuente o copiarlo en el recuadro de texto).

3º Comprobar el mail ya que ahi te enviarán si el programa que has enviado produce una solución correcta, incorrecta, si el tiempo de ejecución es demasiado largo, si te pasas de memoria utilizada...

4º Es muy importante respetar el formato de entrada y salida que te explican en el enunciado de cada problema ya que leer mal los datos o imprimirlos de otra manera a como la piden da lugar a un resultado incorrecto aunque el programa que hayas escrito sea correcto. TENED EN CUENTA que cuando tu envias el programa ellos lo compilan y lo prueban redirigiendole un archivo donde tienen todos los tests que quieren hacerle, de modo que teneis que escribir el programa pensando que se le ha redirigido un archivo de entrada con el formato que ellos te indican en el enunciado.

En fin es muy facil cuando se le coje el truco. En el siguiente post pondré el primer problema elegido...

---------------------------------------> EJEMPLO <---------------------------------------

1er PROBLEMA:

Nº: 10055
Nombre: Hashmat the Brave Warrior
Enunciado: http://acm.uva.es/p/v100/10055.html

Como podeis leer, siempre ponen una pequeña introducción para darle un poco de sentido al problema, algunas veces no sirve para nada y otras veces da alguna pista.

En este caso se trata de un guerrero que solo ataca si sus tropas son mayores que las de otro ejercito. Como INPUT DE EJEMPLO te dicen que habrá una serie de lineas, cada una con 2 enteros que indica el nº de hombres de cada ejercito y como OUTPUT por cada una de estas lineas hay que imprimir un nº que es la diferencia (positiva) de hombres que existe entre ellos.

¿Parece facil no? Pues para desanimar dire que no lo es tanto y de los 46146 que han enviado solución, solo unos 13000 y pico es correcta. Aún así este es de los secillos

¡A programar!

Por ser el primero y como cuesta al principio hacerse un poco con la entrada/salida voy a poner un ejemplo de como seria la de este programa:

int main() {

____variables

____while(scanf(aqui lo que penseis\n) != EOF) {

________buscar solucion para la pareja de nº leida

________printf(lo que penseis\n)
____}
}

Pensad que con el scanf estais leyendo del fichero con el formato que ellos imponen y no de la entrada estandar ya que ellos la redirigen con el fichero de test que tienen.

Por cierto, que un programa que hagais calcule la solucion correcta para la entrada de ejemplo que ellos dan no significa que funcione para todos los casos...

Una ultima cosa, podeis declarar funciones auxiliares pero todo el código fuente debe estar en un único archivo.

gF

USUARIOS REGISTRADOS

Poisonous = [MVida] Pedro Cabrera = 1 Resueltos
LOc0 = [MVida] Antonio López Vivar = 2 Resuelto
Efernand = [MVida] Enrique Fern = 2 Resueltos

Para buscar usuarios: http://acm.uva.es/problemset/search.php y es suficiente con indicar parte del nombre, buscando mvida aparecen de momento solo los de arriba, así que los que estén ya registrados que indiquen su nombre o añadan el tag para poder hacer la búsqueda de todos los de MV solo poniendo mvida...


1er PROBLEMA:

Nº: 10055
Nombre: Hashmat the Brave Warrior
Enunciado: http://acm.uva.es/p/v100/10055.html


2º PROBLEMA:

Nº: 11044
Nombre: Searching for Nessy
Enunciado: http://acm.uva.es/p/v110/11044.html


3er PROBLEMA:

Nº: 10465
Nombre: Homer Simpson
Enunciado: http://acm.uva.es/problemset/v104/10465.html

Los que se hayan registrado sin tag, que indiquen su nombre de registro para que los demás puedan ver sus resultados.

SicKneSs

me parece muy interesante la idea :), mñn me lo leere con mas calma y me registrare y eso... a bote pronto la unica pega que le pongo esq los enunciados esten en ingles, por supuesto que se ingles, pero me da algo de pereza tar leyendo ahora xd.

saludos.

Soltrac

Veamos q entienda el problema...

Solo hay q sacar la diferencia entre 2 números? Entonces como decide si ataca o no? Pq si es solo lo primero, hasta con java se hace con menos líneas q con c++...

Es mas...pensandolo mas friamente, hasta realizandolo con c++ necesitas menos líneas q con c...

No lo he leido muy atentamente, pero no puede ser tan facil joe :S

maRc

Solo un apunte: scanf no devuelve EOF cuando se acaba el fichero, devuelve el número de elementos que ha podido leer ;)

gF

#5 ;) solo un apunte, te equivocas ;)

scanf returns an integer, either the number of values read in, or EOF if an end of file is reached. EOF is a special termination character, specified in stdio.h, which designates the end of a file. If no values are successfully read, scanf returns 0. To use scanf in a program, the file stdio.h must be included.

#4 no es tan fácil como parece, pero tienes que buscar donde esta la pega :P

r2d2rigo

Le he pillado el truco. Reside en esta frase:

The input contains two integer numbers in every line. These two numbers in each line denotes the number of soldiers in Hashmat's army and his opponent's army or vice versa. The input numbers are not greater than 232. Input is terminated by End of File.

Que unida a

Hashmat's soldier number is never greater than his opponent.

Viene a dar que como siempre hagas salida = (primer elemento) - (segundo elemento) la has cagado. Tienes que tener en cuenta que el numero de tropas de Hashmat sera siempre el menor, por lo que si te sale un numero negativo le pasas la funcion abs() y lo imprimes :D

PD: Premio al que me diga que pongo en el bucle principal (C++), que estoy espeso ( ·_.)

gF

#7 El problema del ejercicio está en las líneas que has puesto pero no es eso que tu dices, de echo ya dije por arriba que la salida era la diferencia positiva de los 2 ejércitos. Tened en cuenta TODOS los datos que dan... Hay dato 1 que por tonto e innecesario que parezca es donde se produce el error.

Mi consejo es que lo programéis, probéis los casos de prueba que dan y aparte añadáis vosotros los casos mas extremos que se os ocurran y a ver que pasa...

#7 te voy a ayudar con la entrada / salida de lo que tu quieres hacer para ke el resto vaya viendo;

#include <stdio.h>

int main() {

____int a, b, solucion;

____while(scanf("%d %d\n", &a, &b) != EOF) {

________buscar solucion para a, b

________printf("%d\n", solucion)
____}
}

OJO NO DIGO QUE ESTA FORMA DE HACERLO SEA CORRECTA SINO QUE ES EL ESQUEMA PARA LA MANERA QUE TU HAS PROPUESTO.

cabron

Pues no sé, te empeñas tanto en decir que la pregunta tiene trampa, que me haces dudar de que la solución sea sencilla, pero diría que es:

unsigned int calcular(unsigned int a, unsigned int b)
{

&nbsp;&nbsp;&nbsp; if (a > b)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return a - b;
&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return b - a;
}

Y en el printf iría el resultado de calcular()

LOc0


Problem A

Hashmat the brave warrior

Input: standard input

Output: standard output



Hashmat is a brave warrior who with his group of young soldiers moves from one place to another to fight against his opponents. Before fighting he just calculates one thing, the difference between his soldier number and the opponent's soldier number. From this difference he decides whether to fight or not. Hashmat's soldier number is never greater than his opponent.

Input

The input contains two integer numbers in every line. These two numbers in each line denotes the number of soldiers in Hashmat's army and his opponent's army or vice versa. The input numbers are not greater than 232. Input is terminated by End of File.



Output

For each line of input, print the difference of number of soldiers between Hashmat's army and his opponent's army. Each output should be in seperate line.



Sample Input:
10 12
10 14
100 200



Sample Output:
2
4
100
_________________________________________________________

¿Es un concurso de programación o de acertijos? Porque si es lo primero me parece un poco chorra ¿no?

Salu2 ;)

PD:

¿Parece facil no? Pues para desanimar dire que no lo es tanto y de los 46146 que han enviado solución, solo unos 13000 y pico es correcta. Aún así este es de los secillos OMG :O

gF

#9 Registrate en el juez online como puse en el primer post y manda la solución, ya verás que te dice.

Repito que hay un dato que por ahora parece no importarle a nadie y por el que el problema no es tan sencillo.

#10 La idea es que cada cierto tiempo elegiría un nuevo problema y es para aquellos que les guste resolver problemas de ingenio.

Por eso digo que os registréis en la web metiendo al final del nombre [MV] y así se podrá saber que usuarios han acertado cada problema que proponga.

AlKhwarizmi

Sobre el tema que comentas al principio de C y C++ vs. Java: la organización del concurso de la ACM no pone ninguna limitación significativa a usar Java. Lo que tiene limitaciones es el juez online de la web de la Universidad de Valladolid a la que has enlazado. Este juez tiene implementado para Java sólo el GCJ (compilador antiguo y que no soporta toda la API) y además lo tiene hecho de forma chapucera y con limitaciones. Pero en el concurso "de verdad" no hay problema.

Yo participé en el concurso tres veces, y ahora voy como "coach" de los equipos de mi universidad (así que si tenéis alguna duda sobre el funcionamiento o algo, podéis preguntarme si queréis :D), y personalmente siempre les recomiendo que usen Java. Si uno se conoce la API, las cosas que ya trae hechas (como todo tipo de estructuras de datos, aritmética con números grandes, funciones para polígonos, etc. etc.) pueden ahorrar mucho tiempo. Aparte de que al ser de más alto nivel y más fácil de debuggear, es más efectivo para un concurso como éste en el que lo que cuenta es la velocidad de desarrollo.

LOc0

A ver, pueden ser iguales, pero aún así no veo el problema...

Salu2 ;)

Edito: Como no sea algún problema de tamaño máximo de variables o alguna cosa así no lo veo ¬¬...

gF

#12 Yo sugiero no usar Java pq en principio el juez que vamos a usar es el de la universidad de Valladolid precisamente.

Por cierto tu si sabes la pega de este problema no? xD

LOc0

¿Se pueden usar librerías de terceros en el concurso?

Salu2 ;)

cabron

Yo es que lo único ue veo es que al ser el valor máximo 232, en una máquina donde int compile a un entero de 16 bits, se desbordaría el tipo de datos, y habría que cambiar las variables por unsigned long int, no sé, no encuentro ese supuesto dato en el enunciado que hace que la solución este mal :?

#11:

Me he registrado pero no me mandan el mail

gF

No, librerias estandar y todo el codigo en un mismo fichero.

gF

#16 Ese es el problema y aun usando unsigned long vas a tener un rango desde 0 hata 232 - 1

cabron

Bueno, pues se pone un float y listo ^^

AlKhwarizmi

Sí, el problema es el overflow, en muchos problemas de éstos aparece.

maRc

#6 touché.

Por cierto, he enviado mi programa y me dice:

Dear marbosjo:

Your program HAS NOT been submitted.
The Contest is already end or still has not begun.
Sorry! :'-(

--
The Online Judge

LOc0

Ojo a esto:


Your program has tried to use a non allowed function (such as fopen(),
system(),...). Remember that you only need to read from the standard
input, to process and to write into the standard output (Note: all
programs submited are logged in this system ;-) .

If you still are sure that you are using only standard functions, please
contact the administrator.

Salu2 ;)

PD: Parece que ahora sí, pero a medias xD:


Your C program has solved Ok the problem 10055 (Hashmat the Brave Warrior)
in 0.943 seconds using as much as 396 kbytes of virtual memory.
Congratulations!

Warning: Your program would get a Presentation Error in a true contest.
The 24-hours judge interpretes it as an "Accepted" problem.

gF

#21 eso es que no lo has enviado bien o habrás introducido mal algún dato

#22 el warning ese se debe a que en la presentación has debido meter alguna linea en blanco de más o cualquier cosa que hace que el formato de salida no sea el indicado

Poisonous

Ya estoy registrado, con tag y todo xd, solo 1 duda, "el problema d esta semana" es local a mediavida no? Quiero decir, ellos ponen plazos para entregar los programas y ponen 1 cada semana? o puedes elegir resolver el que mas te llama y cuando quieras?
Vamos, lo que quiero decir es si el problema semanal es de este post para darle mas vidilla y trabajar todos en algo parecido?

LOc0

#23

¡Qué va! Eso pensaba yo, pero es que para que te lo de por "aceptado" tienes que usar un tipo de dato entero. No vale con coma flotante (aunque los dos tengan 8 bytes).

Total, que cambiando eso ya me lo da por "aceptado", pero (y aquí viene lo mejor), compilado con Dev-Cpp 4.9.9.2 NO funciona correctamente :D (Para troncharse)

No lo veo justo, pero el Judgator no razona demasiado xD.

Salu2 ;)

gF

#24 es para el foro solamente, tu puedes hacer los que quieras de los que hay, pero vamos es por de algún modo hacer todos el mismo

gF

En #2 esta el enunciado del siguiente problema que he propuesto, por ahora son fáciles para ir calentando.

Por cierto los que os hayáis registrado en el juez online, modificar vuestro nombre añadiendo el tag [MV] o [MVida] para que todos podamos mirar las estadísticas de los demás de manera fácil...

Poisonous

Mas dudas, se supone q el algoritmo ha d ser optimo? o vale con que resuelva el problema?

gF

#28 basta con que resuelva el problema, no tiene pq ser óptimo, aunque es cierto que sí existe una limitación en el tiempo de ejecución que para casi todos los problemas o por lo menos para los que yo he visto es de 10 segundos. Si supera ese limite el juez te enviará el mensaje "Time Limit Exceeded" aunque tu programa resuelva el problema correctamente.

AlKhwarizmi

#25: Sobre lo que dices de la coma flotante, el juez automático no mira el código de tu programa, sólo mira las salidas que da comparándolas con una salida deseada. Si coinciden, está bien, independientemente de lo que hayas usado por dentro.

Tu problema seguramente es que, al usar coma flotante, pierdes precisión en los números muy grandes. Piensa que los números en coma flotante están representados en la máquina mediante una notación exponencial (como cuando escribes 5.53*107, sólo que usando 2 en vez de 10 al ser en binario).

Esto quiere decir que, cuando trabajas con números grandes, la precisión puede no darte para distinguir un entero de otro. Por ejemplo 232-1 puede ser representado como 232, porque sería algo como 1.9999999999...*232 y la mantisa no da para representar ese número.

No sé si me explico, si no se ha entendido intento explicarme mejor :)