jueves, 2 de agosto de 2012

Problema de la UVA 12318

Recientemente elegimos este problema para trabajar con él. Básicamente, te dan un polinomio de grado k menor o igual a 10 y la idea es averiguar cuantos resultados distintos modulo n+1 (con n menor o igual a 10 000 000) podemos obtener evaluándolo con los enteros del 0 al m menor o igual a 100 000 . Todos los coeficientes del polinomio son mayores o iguales a 0 y menores o iguales a n. Creo que lo primero es ver cómo evaluar rápidamente el polinomio módulo n+1 y después ver cómo averiguar cuántos resultados fueron diferentes. El límite de tiempo es de 4 segundos, y el problema es multicasos. La descripción del problema es la siguiente:

  Digital Roulette 

John is developing a videogame that allows players to bet in a wall roulette. Players may bet for integer numbers from 0 to N, for some N$ \ge$ 0 that represents the maximum number in the roulette.

Of course, the roulette behaves digitally. As a matter of fact, John designed its way to choose a value in the interval 0..N (the result of spinning the roulette) with a digital trigger that moves the roulette with a force that depends on an integer value x randomly chosen in the interval 0..M, where M$ \ge$ 0 (M is the maximal appliable force). The roulette turns around a distance equivalent to P(x), where P is a polynomial with integer coefficients. One distance unit represents a displacement of one roulette number, counting clockwise.


It is clear that some result values may be produced by different chosen force values. Also, depending on the mechanism parameters, some numbers in the roulette may be not attainable regardless of the force value. For example, if N = 7, M = 5 and P(x) = x2 + 1, the mechanism can generate only three different results:

\epsfbox{p12318.eps}


John wants to know how many different result values may be attained by his mechanism. Can you help him?

Input 

There are several cases to analyze. Each case is described by three lines:
  • The first line contains two non-negative integer numbers N and M, separated by a blank ( 1 $ \leq$ N $ \leq$ 107, 0 $ \leq$ M $ \leq$ 105).
  • The second line contains an integer k, the grad of the polynomial P ( 0 $ \leq$ k $ \leq$ 10).
  • The third line contains k + 1 integers a0, a1,..., ak separated by blanks, indicating the integer coefficients that define the polynomial P, i.e., P(x) = akxk + ... + a1x + a0. You can assume that 0 $ \leq$ ai $ \leq$ N for each 0 $ \leq$ i $ \leq$ k. If k > 0 then you may assume that ak $ \neq$ 0.
The last test case is followed by a line containing two zeros.

Output 

For each case, print one line indicating how many different numbers are attainable by John's mechanism.

Sample Input 


7 5
2
1 0 1
99 10
0
5
99 10
1
5 25
99 10
1
3 29
99 10
2
3 29 31
0 0

Sample Output 


3
1
4
11
10



6 comentarios:

  1. Intenté usar las tags pre y code, pero no me deja, por favor quien tenga la cuenta administrativa de este blog cheque si es posible permitirlo.

    Roberto

    ResponderEliminar
  2. Les mando un pseudocódigo que hice rápidamente, podría tener errores, luego lo checo con más detalle
    -------------

    int N =0
    int M
    int a00 =0
    ...
    int a10 =0

    leer N, M, a00, ... , a10
    while ( N!= 0) {

    int contador_obtenidos = 0
    // esta variable indica la cantidad de tiros diferentes que se han obtenido

    obtenidos es un array de N booleanos inicializados en FALSE
    // este arreglo registra los tiros que se han obtenido al menos una vez

    int x = 0

    while (contador_obtenidos <N && x <= M) {
    tiro = mod(polinomio(x,&a00,...,&a10),N)
    if (obtenidos(tiro) == FALSE) {
    obtenidos(tiro) = TRUE
    contador_obtenidos++
    }
    x++
    }

    imprimir contador_obtenidos

    N=0
    leer N, M, a00, ... , a10
    }


    int function polinomio(x, &a00, ..., &a10) {
    int p
    p = a0 + a1*x + ... + a10*x10
    return p
    }

    ResponderEliminar
  3. este pseudocódigo que les puse está hecho bajo una idea de fuerza bruta, tal vez existan maneras más elegantes.

    ResponderEliminar
  4. El uva acepto ese código? dudo mucho pues si calculan el polinomio de la funtion polinomio de manera anidada eso lo haría tantito más rapido... Por guapa subiremos unas notitas basicas de la definición de algoritmo "más elegante" que hemos visto.

    ResponderEliminar
  5. no he escrito el código, lo que publiqué aquí es solamente un bosquejo

    ResponderEliminar
  6. hay que ver que pasa pero siennnto que tendremos que usar ese algoritmo que habla sobre x`b congruente con a (mod c), con b corriendo... si hay que revisar bien este problema

    ResponderEliminar