Archivos Mensuales: marzo 2013

Clase 16 de Marzo, Backtracking y Busqueda Binaria.

Clase 16 de Marzo 2013

Se les comunica que los proximos dos fines de semana no habra clase, entonces nuestra proxima clase seria el sabado 7 de abril, de todos modos yo voy a estar contestando correos, aquellos que tengas dudas de los problemas de tareas no duden en escribirme a rodrigo.burgos@gmail.com

Les coloco los codigos que hicimos en clase:

Permutaciones

Como sacar todas las permutaciones de una cadena donde todos los elementos son diferernte:

# include <stdio.h>
# include <string.h>

char cad[100], path[100];
char mark[100];

void backtrack( int level ){
  int x;
  if( level == strlen( cad )){
  	cad[ level ] = '\0';
    printf("%s\n", path);
  }
  for( x = 0; x < strlen( cad ); x++)
    if( mark[x] == 0 ){
  	   mark[x] = 1;
  	   path[ level ] = cad[x];
  	   path[ level + 1] = '\0';
  	   backtrack( level + 1);
  	   mark[x] = 0;
    }
}

main(){
  while( scanf("%s", cad) != EOF ){
     memset( mark, 0, sizeof( mark ));	
     backtrack( 0 );
  }
  return 0;	
}

Búsqueda Binaria.

la función busbiniter es la forma iterativa de la búsqueda binaria, también tenemos la función busbinrec que es la función recursiva.

# include <stdio.h>
# include <string.h>

int n;
int list[100000];

int busbiniter( int inf, int sup, int val ){
   int med;
   while( inf <= sup ){
   	  med = (inf + sup ) / 2;
	  if( list[ med ] == val ) return med;
      if( list[med] < val ) inf = med + 1;
      else sup = med - 1;
   }
   return -1;
}

int busbinrec( int inf, int sup, int val ){
  int med = ( inf + sup ) / 2;	
  if( inf > sup ) return -1;
  if( list[ med ] == val ) return med;
  if( list[med] < val ) return busbinrec( med + 1, sup, val);
  return busbinrec( inf, med - 1, val);
}

main(){
   int x, val;
   n = 0;
   for( x = 0 ; x <= 100000; x+= 3) list[n++] = x;
   while( scanf("%d", &val) != EOF ){
    printf("%d\n",  busbiniter( 0, n - 1, val ) ) ;
   }
   return 0;	
}

Tour del caballo
Este código resuelve el problema que vimos en clase, dado el un tablero de ajedrez de N x N, y la posición inicial del caballo encontrar un camino donde el caballo visite todos los cuadros del tablero.

# include <stdio.h>
# include <string.h>

int board[100][100];

int dr[8] = {2,2,-2,-2,-1,-1,1,1};
int dc[8] = {1,-1,1,-1,2,-2,2,-2};

int n;

int backtrack(int level, int r, int c){
  int dir, x, y, res = 0;
  if( level == n * n + 1 ){
    for( x = 0; x < n; x++){
      for( y = 0; y < n; y++) printf("%3d", board[x][y]);
      printf("\n");
    }
    printf("---\n");
    return 1;
  }
  if( r < 0 || r >= n || c < 0 || c >= n ) return 0;
  if( board[r][c] != 0 ) return 0;
  board[r][c] = level;
  for( dir = 0; dir < 8; dir++)
    res += backtrack(level + 1,  r + dr[ dir ] , c + dc[ dir ] );
  board[r][c] = 0;
  return res;
}


main(){
  int posr, posc;
  int r;
  while( scanf("%d %d %d", &n, &posr, &posc) != EOF ){
  	 memset(board, 0, sizeof( board ));
     r = backtrack(1, posr, posc);
     printf("%d\n", r);
  }
  return 0;	
}

Problema del Sudoku
El siguiente programa resuelve el problema del sudoku, como vismo en clase es muy util utilizar el bactraking y para evitar crecer mucho el codigo utilizamos la tecnica de hash, con la filas, columnas y los cuadrantes.


# include <stdio.h>
# include <string.h>

int hashRow[10][10];
int hashCol[10][10];
int hashCua[10][10];

int numcuad[10][10];

char sudoku[10][10];

int print(){
	int x, y;
      for( x = 0; x < 9; x++){
        for( y = 0; y < 9; y++) printf("%c", sudoku[x][y]);
        printf("\n");
      }
    printf("---\n");
}

int backtrack( int row, int col ){
   int dig, x;
   if( row == 10 ){
	  print();
      return 1;	
   }
   if( col == 10 ) return backtrack( row + 1, 1 );
   if( sudoku[row-1][col-1] != '_') return backtrack( row , col + 1);
   for( dig = 1 ; dig <= 9; dig++){
      if( hashRow[ row ][ dig ] == 1 ) continue;	
      if( hashCol[ col ][ dig ] == 1 ) continue;	
      if( hashCua[ numcuad[row -1][col -1 ] ][ dig ] == 1 ) continue;
      hashRow[ row ][ dig ] = 1;
      hashCol[ col ][ dig ] = 1;
      hashCua[ numcuad[row -1][col -1 ] ][ dig ]= 1;
      sudoku[row-1][col-1] = '0' + dig;

      if( backtrack( row, col + 1) ) return 1;

      hashRow[ row ][ dig ] = 0;
      hashCol[ col ][ dig ] = 0;
      hashCua[ numcuad[row -1][col -1 ] ][ dig ]= 0;
      sudoku[row-1][col-1] = '_';
   }
   return 0;	
}

main(){
  int x, y, ncases, cases, row, col;
  for(x = 0; x < 9; x++)
  for( y = 0; y< 9; y++){
      numcuad[x ][ y ] = ( ((x / 3) ) * 3 +  (y / 3) ) + 1;	
  }
  for( scanf("%d", &ncases), cases = 1; cases <= ncases; cases++ ){
  	memset( hashRow, 0, sizeof( hashRow));
  	memset( hashCol, 0, sizeof( hashCol));
  	memset( hashCua, 0, sizeof( hashCua));
  	for(row = 0; row < 9;row++){
  	  scanf("%s", sudoku[row]);
  	  for( col = 0; col < 9; col++) 
  	     if( sudoku[row][col] != '_'){
  	         hashRow[ row + 1 ][ sudoku[row][col] - '0'] = 1;	
  	         hashCol[ col + 1 ][ sudoku[row][col] - '0'] = 1;	
  	         hashCua[ numcuad[row][col] ][ sudoku[row][col] - '0'] = 1;
  	     }
  	}
  	backtrack( 1, 1 );
  }
  return 0;
}

Problemas:

Backtracking

http://uva.onlinejudge.org/external/1/167.html (Problema de las 8 reinas, utilizen la tecnica de hash, sobre fila, columna y diagonales, pueden poner una matriz como hicimos en el problema del sudoku para saber que diagonal le corresponde, recuerden que son dos tipos de diagonales).

http://uva.onlinejudge.org/external/5/524.html ( Problema de bactracking y primos , ya estan listos para estos problemas ).

http://uva.onlinejudge.org/external/5/574.html (Pueden ordenar los elementos para hacer una poda eficiente al bactrackign).

http://uva.onlinejudge.org/external/6/624.html

http://uva.onlinejudge.org/external/6/628.html

http://uva.onlinejudge.org/external/105/10582.html

http://uva.onlinejudge.org/external/6/677.html ( revisen la primera clase y el probleam del The lord of the ring, para ver como crear una matriz de adyacencia, en la siguiente clase veremos grafos, pero con lo que saben pueden resolver este problema).

http://uva.onlinejudge.org/external/7/750.html (Otro problema de las 8 reinas).

http://uva.onlinejudge.org/external/103/10344.html

http://uva.onlinejudge.org/external/8/868.html (aun que se puede hacer un algoritmo mas rapido con memorizacion es buena practica para un backtraking.)

http://uva.onlinejudge.org/external/103/10309.html (recursividad con memorizacion, notar que todas son de 10 x 10 , por tanto solo hay 10 1’s o 0’s , ¿eso no les recuerda a los bits ?.)

Binary Search:

http://uva.onlinejudge.org/external/106/10611.html
http://uva.onlinejudge.org/external/107/10742.html
http://uva.onlinejudge.org/external/110/11057.html
http://uva.onlinejudge.org/external/118/11876.html

Suerte, y recuerden que pueden resolver problemas aun que no esten en la lista.

Saludos.

Clase 2, 9 de Marzo

Buenos días a todos, les comparto el código que hicimos en clase:

/*
  Autor : Rodrigo Burgos Dominguez.
  Problema: Regional 2006 ACM Mexico, 
*/
# include <stdio.h>
# include <string.h>

# define MAX 1000000

int prime[MAX +1], nprime, hash[ 256], hashprime[ MAX + 1];
char criba[MAX+1], cad[MAX+1];

void update( int n, int oper ){
   int x, pt;
   for( x = 0; x < nprime && x <= n; x++){
      for( pt = prime[x] ; pt <= n ; pt *= prime[ x ])	
          hashprime[ x ] += ( n / pt ) * oper;
   }	
}

int abso( int a ){ return a < 0 ? -a: a; }

int potencia( int a, int b ){
  int res = 1;
  for( ; b > 0  ;  b-- ) res *= a;
  return res; 	
}


main(){
  int x, y, ncases, cases, res, pot, val, n;
  nprime = 0;
  for( x = 2; x <= MAX ; x++)
    if( criba[ x ] == 0 )
       for( y = x * 2, prime[ nprime++ ] = x ; y <= MAX ; y+= x) criba[y] = 1;
  for( scanf("%d", &ncases), cases = 1; cases <= ncases ; cases++ ){
  	scanf("%s", cad);
  	n = strlen(cad);
  	memset( hash, 0, sizeof( hash ));
  	memset( hashprime, 0, sizeof( hashprime));
  	for( x = n - 1; x >= 0 ; x-- ) hash[ cad[ x ] ]++;
  	update( n , 1 );
  	for( x = 'a' ; x <= 'z'; x++){
  	  update( hash[ x ] , -1);
  	}
  	res = 1;
  	for( x = 1; x < n; x++)
  	  if( prime[x] != 5 )
  	     res  = (res * potencia( prime[x], hashprime[ x ])) % 10;
  	pot = abso( hashprime[ 0 ] - hashprime[ 2 ]);
  	val = ( hashprime[0] < hashprime[2]) ? 5 : 2; 
  	res = (res * potencia( val, pot) ) % 10;
  	printf("%d\n", res);
  }
  return 0;	
}

Lo que vimos en clase, que son los primos como sacarlos con la criba de Eratóstenes, factorizar un numero, conteo rápido de primos en un Factorial, saber obtener el numero de ceros y el ultimo numero distinto de cero.

Aquí les dejo los problemas para que practiquen, necesito que los envíen a la uva para ver si están entendiendo , si tienen dudas envíenme un correo a rodrigo.burgos@gmail.com con sus respectivas dudas.

Problemas:

Prime Cuts
http://uva.onlinejudge.org/external/4/406.html

Goldbach’s Conjecture
http://uva.onlinejudge.org/external/5/543.html
nota: 6 <= n <= 1,000,000 utilizen un hash para ver si un numero es primo (pueden usar el arreglo de la criba ) y solo iterar los 78,000 primos.

recuerden que la lectura de este seria asi:

while( scanf("%d", &n) != EOF && n != 0 ){

}

Problem G: Simply Emirp
http://uva.onlinejudge.org/external/102/10235.html

Problem E – Prime Words
http://uva.onlinejudge.org/external/109/10924.html

Problem F: The primary problem.
http://uva.onlinejudge.org/external/109/10948.html

Factors and Factorials
http://uva.onlinejudge.org/external/1/160.html
Nota: utilicen la técnica de conteo que les enseñe, de ver cuantos dos , tres, cincos hay en un N factorial para resolver este problema. Lean bien la salida como se debe hacer, si tiene dudas me escriben sus dudas.

Product of digits
http://uva.onlinejudge.org/external/9/993.html

How many zeros and how many digits?
http://uva.onlinejudge.org/external/100/10061.html
Nota: Deben leer sobre lo logaritmos.

Divisors
http://uva.onlinejudge.org/external/2/294.html

Factorial Factors
http://uva.onlinejudge.org/external/8/884.html

I – Find Terrorists
http://uva.onlinejudge.org/external/12/1246.html

Problem D – Count the factors
http://uva.onlinejudge.org/external/106/10699.html

Twin Primes
http://uva.onlinejudge.org/external/103/10394.html

Almost Prime Numbers
http://uva.onlinejudge.org/external/105/10539.html
Nota: el valor hiigh < 10^12 , esto es muy grande, pero deben darse cuenta, que un almost prime es un no primo que es divisible por un solo primo esto quiere decir que un almost primer es de la forma P^2, P^3 … P^n, como el valor mas peque es p^2, si buscamos un primo que sea mas grade de un 1000,000 = 10^6, su cuadrado seria mayor 10^12 que es nuestro tope, entonces basta con tener todos los primos menores a 10^6.

Factorial Frequencies
http://uva.onlinejudge.org/external/3/324.html

Problem A – Prime Distance
http://uva.onlinejudge.org/external/101/10140.html

Just the Facts
http://uva.onlinejudge.org/external/5/568.html

Prime Factors
http://uva.onlinejudge.org/external/5/583.html

Problem D: GCD LCM
http://uva.onlinejudge.org/external/113/11388.html

Largest Prime Divisor
http://uva.onlinejudge.org/external/114/11466.html
el numero es menor o igual 14 digitos, esto quiere decir que con un nomero 10^7 es suficiente para saber el cual es el primo mas grande.

Problem C: Composite Prime
http://uva.onlinejudge.org/external/110/11086.html

Clase 2 Marzo 2013

Coloco las paginas que les mencione el la clase pasada:

http://uhunt.felix-halim.net/

http://uva.onlinejudge.org/index.php

Deben crear su cuenta:, para poder enviar problemas

Otras paginas donde puede practicar es en topcoder
http://www.topcoder.com/tc
Y para ver reseñas de los problemas que se han puesto en sus concusos revisen esta liga:
http://apps.topcoder.com/wiki/display/tc/Algorithm+Problem+Set+Analysis
También tienen tutoriales.
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=alg_index

Esta es la lista de problemas de esta semana:

http://uva.onlinejudge.org/external/121/12149.html
(formula , puedes usar una formula y un for).
La lectura seria algo como esto:

main( ){

    while( scanf(“%d”, &n) ¡= EOF && n ¡= 0 ){
     …..
     }
     return 0;

    }

ya que dice que termina cuando la línea contenga un 0.

http://uva.onlinejudge.org/external/121/12157.html voy a poner como se resuelve este en java para que los que usen Java no tengan problemas de enviar sus código:


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	
	public final static int COST_PER_COMPANY[] = {10,15};
	public final static int TIME_PER_COMPANY[] = {30,60};
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		for(int ncases = scan.nextInt(), cases = 1 ; cases <= ncases ; cases++ ){
			int cost[] = new int[2];
			Arrays.fill(cost, 0);  // esto es lo mismo que el memset en C o C++, solo que hay que hacer
								   // por cada dimencion de nuestro arreglo.
			int numCalls = scan.nextInt();
			for( int x = 0; x < numCalls ; x++ ){
				int callDuration = scan.nextInt();
				for( int company = 0 ; company < 2; company++ ){
					cost[ company ] += ( (callDuration / TIME_PER_COMPANY[ company ] )+ 1) * COST_PER_COMPANY[company];
				}
			}
			System.out.printf("Case %d: ",  cases);
			if( cost[ 0 ] == cost[ 1 ]){
				System.out.printf("Mile Juice %d\n", cost[ 0 ] );
			}else{
				if( cost[ 0 ] < cost[ 1 ])
					System.out.printf("Mile %d\n", cost[ 0 ] );
				else
					System.out.printf("Juice %d\n", cost[ 1 ] );
			}
		} 
	}
}


Como pueden ver, no agrego el pakage, y la clase se llama Main, esto es muy importante, en la uva lo que envien en codigo Java lo guardara en un Main.java y lo compilara, si no tiene la clases el nombre de Main les mandara un compile error:
Main.java:5: class P12157 is public, should be declared in a file named P12157.java
public class P12157 {
^
1 error

Entonces abusados con esto.

les dejo los demas problema:

http://uva.onlinejudge.org/external/123/12372.html
http://uva.onlinejudge.org/external/123/12342.html
http://uva.onlinejudge.org/external/100/10055.html
http://uva.onlinejudge.org/external/100/10071.html
http://uva.onlinejudge.org/external/100/10038.html
http://uva.onlinejudge.org/external/100/10035.html
http://uva.onlinejudge.org/external/101/10189.html
http://uva.onlinejudge.org/external/101/10110.html
http://uva.onlinejudge.org/external/101/10127.html
http://uva.onlinejudge.org/external/122/12289.html
http://uva.onlinejudge.org/external/122/12250.html
http://uva.onlinejudge.org/external/122/12279.html
http://uva.onlinejudge.org/external/122/12243.html