Programacion, ACM ICPC, UVa Online Judge

Archivo para la Categoría "Java"

UVa Online Judge – 893 – Y3K Problem

El link del problema es el siguiente:
893 – Y3K Problem

El problema es de tipo Ad hoc y se puede resolver fácilmente con Java utilizando la clase Calendar.
El problema nos da una fecha y una cantidad de días después de la fecha dada, y hay que calcular la fecha resultante.

Como dije se puede hacer muy fácil en Java utilizando Calendar.
Al leer, primero es el numero de días que avanzaremos, y después la fecha.
Con el método «set» de Calendar colocamos la fecha actual y utilizando el método «add» con el valor DAY_OF_MONTH, agregamos la cantidad de días que el caso especifico.

La parte importante seria esta:
Calendar c;
c.set(year,month-1,day);
c.add(DAY_OF_MONTH,plus);

E imprimir en el formato indicado.

Codigo en Java

UVa Online Judge – 1230 – MODEX

El link del problema es el siguiente:
1230 – MODEX

Lo que nos piden es elevar un numero «x» a una potencia «y» y obtener el modulo «n» de ese conjunto de operaciones.
Una solución es implementar una exponenciación rápida modular, que consiste en ir sacando los módulos al mismo tiempo que se eleva a la potencia para no desbordar el tipo de dato.
Otra solución mas corta es utilizar Java y la clase BigInteger ya tiene implementado expmod que hace exactamente lo que el problema solicita.

Código en Java

UVa Online Judge – 748 – Exponentiation

El link del problema es el siguiente:
748 – Exponentiation

Lo que nos pide el problema es elevar un numero en punto flotante a una potencia.
Lo complicado aca es que hay que mantener todos los digitos de presicion, asi que lo mas recomendable es usar Java con BigDecimal.

Al utilizar el metodo pow del BigDecimal, si lo imprimimos tal cual, tendremos el problema que el resultado lo deja como notacion cientifica. Para solucionarlo lo que usaremos es el metodo toPlainString() de BigDecimal que nos regresa un String con todos los digitos.

Lo unico a tener en consideración es que cuando la parte entera es igual a cero, no se coloca el cero y se empieza desde el punto decimal, y que hay que mostrar el numero correcto de decimales.
Para los decimales solo contamos el numero de elementos de la parte decimal del numero que vamos a elevar y multiplicarlo por la potencia que vamos a elevar.
Ejemplo:
95.123 12
Numeros en la parte decimal = 3
Potencia = 12
Numero de dígitos en la parte decimal despues de elevar a la potencia = 3*12

1.0100 12
Numero en la parte decimal = 2
Potencia = 12
Numero de digitos en la parte decimal despues de elevar a la potencia = 2*12

Código en Java

UVa Online Judge – 12019 – Doom’s Day Algorithm

El link del problema es el siguiente:
12019 – Doom’s Day Algorithm

El problema es muy sencillo de resolver con Java utilizando Calendar.
En el problema nos dan el Mes y el Dia, y el año es siempre 2011.
Utilizando el metodo set del calendar, mandamos los 3 parametros y utilzando el metodo get con la constante Calendar.DAY_OF_WEEK, podemos fácilmente obtener el día de la semana con las constantes que igual Calendar proporciona.
Calendar.SUNDAY, Calendar.MONDAY, etc. O utilizando su valor numérico correspondiente, Sunday = 1, Monday = 2, etc.
Lo único importante, es que hay que restarle 1 al mes, ya que Enero es el mes 0, no el mes 1.

Código en Java

Segmentación de Imágenes (Cortes Normalizados)

El algoritmo de cortes normalizados es utilizado para la segmentación de imágenes.
La implementacion que realice fue hecha en Java.
A continuación dare una breve explicacion de como el algoritmo funciona.

SI están interesados en mas detalles del algoritmo, pueden visitar el siguiente link:

http://www.cs.berkeley.edu/~malik/papers/SM-ncut.pdf

Descripción del Algoritmo

Para su implementación se plantea a la imagen como un Grafo.
Dado un grafo G y un conjunto de vértices V, donde cada vértice representa un pixel en la imagen, y un conjunto de aristas E, en la que se representa la relación entre los pixeles con un peso W, hay que encontrar un corte que divida al grafo en dos conjuntos, A y B.
El corte se define de la siguiente manera:

Esta partición en dos conjuntos debe cumplir que la asociación entre los pixeles entre A y B sea mínima y la asociación entre los pixeles de cada uno de los conjuntos sea lo mayor posible.
La idea es no considerar sólo el valor de los arcos sino las relaciones entre los pixeles de modo de distinguir entre grupos aislados y poco conectados frente a grupos aislados pero muy conectados.
La descripción queda expresada por la siguiente formula:

Donde assoc(A,V) nos da la conexión total de los nodos pertenecientes al conjunto A con todos los nodos del grafo y assoc(B,V) esta definido de manera similar.De manera similar nosotros podemos definir el total de la asociación de los grupos para una partición dada:

Donde assoc(A,A) y assoc(B,B) son los pesos de las aristas que conectan los nodos de cada conjunto respectivamente.
Nosotros podemos definir un corte en términos de la asociación y disociación ya que están relacionados por:

Con esto, podemos encontrar que el punto optimo de corte esta dado por:

A esto se llega de la siguiente manera:

Ecuación original

Sustituyendo por la ecuación anterior

Acá podemos notar que buscamos un criterio, consiste en minimizar la disociación de los conjuntos y maximizar la asociación entre los conjuntos. En el algoritmo utilizamos este corte normalizado como criterio de partición.
Para poder computar el corte, necesitamos resolver un sistema de eigenvalores dado por:

Donde W se construye como una matriz por la siguiente función:

Y la matriz D se construye como:

Pero primero hay que transformarlo en un sistema de eigenvalores estándar, que esta dado por:

 esta dada por:

Entonces hay que resolver el sistema dado por:

Primero hay que checar si la matriz es simétrica, si lo es, entonces procedemos a resolver primero generando una matriz tridiagonal y después resolver por el algoritmo QL que resuelve el sistema y nos regresan los eigenvalores y eigenvectores. Si la matriz no es simétrica se procede a resolver mediante una reducción de la matriz Hessenberg no simétrica una forma Schur.

Una vez resuelto el sistema, elegimos los eigenvectores asociados a los primeros valores de los eigenvalores más pequeños, de tal manera que estos tiendan a cero.

Cada valor del eigenvector esta asociado con un pixel de la imagen, como muestra el siguiente esquema:

Después calculamos con la formula  un valor de tal manera que podamos dividir el eigenvector en dos conjuntos y poder dividir la imagen.

Esto se realiza para cada uno de los eigenvectores que se seleccionaron.

Para la división, lo que hacemos es comparar el valor obtenido con el valor i-esimo del iegenvector para saber si el pixel asociado, pertenece al conjunto A o al conjunto B.

Una vez obtenido el conjunto A y el conjunto B, se calcula su Varianza, de tal manera que, el conjunto que tenga la menor Varianza es el conjunto a representar en la imagen.

Este proceso se realizara mientras se soliciten más particiones y mientras tengamos eigenvectores que cumplan el criterio de que su eigenvalor sea cercano a cero.

Acá muestro algunos resultados obtenidos del algoritmo.
Las imágenes utilizadas son de un maximo de 30×30 pixeles.
Si alguien tiene alguna duda acerca de la implementación, puede hacérmelo saber, para poder desarrollar mas la parte que especifiquen, siempre y cuando este en mis posibilidades.