miércoles, 12 de octubre de 2011

Move To Invert

A triangle made of coins of height h is as follows
It has h coins at the base and h-1 coins one level above base and so on.(Coins are placed as shown in the figure below)
And at the top most level there will be only one coin
Now given h the task is to invert this triangle by moving minimum number of coins. For example when h=4 triangle is



For h=4 at least 3 coins must be moved to invert it.
Input

In the first line N will be given and then N lines follow with each line having a integer which is the height of triangle in that test case.00≤h<1010;
Output

For each test case output in a seperate line the minimum number of moves required to invert the triangle. Output fits in long long data type 


Example
Inputt:
1
3

Output:
2


http://www.spoj.pl/problems/MINCOUNT/

Solucion: 

Buscando en internet se pueden encontrar muchas funciones que asocian el numero de filas del triangulo con la cantidad de movimientos minimos necesarios para invertir el triangulo. Muchas de estas funciones requieren muchas operaciones redundantes.

Pero aca usaremos una formula que se deduce facilmente de observar la relacion entre la cantidad de monedas del triangulo y la cantidad minima de movimientos necesarios para invertir el triangulo,  esta formula es algo más simple que muchas de las que se pueden encontrar en internet.

 

           
donde:

N° de fichas = N° filas( N° filas + 1 )/2

De la tabla se pude conjeturar que:

N° de mov. = N° de fichas / 3 = N° filas( N° filas + 1 )/6


import java.io.*;

public class MoveToInvert
{
    public static void main( String[] args ) throws Exception
    {
        BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
  
        /** Usamos un buffer para mostrar la salida **/
        int tamanio=0, longitud;
        char[] salida = new char[ 500000  ];String cadena;
  
  
        int numCasos = Integer.parseInt( br.readLine() );
  
        long N;   // Numero de filas del triangulo   
 
        for( int i = 0; i < numCasos; i ++ )
        {
            N = Long.parseLong( br.readLine() );
   
            cadena= invertir( N ) ;
   
            longitud = cadena.length();
   
            // Copiamos los caracteres de la cadena al buffer de salida
            cadena.getChars( 0, longitud, salida, tamanio );
            tamanio = tamanio + longitud;
   
            // Anadimos el caracter de fin de linea
            salida[ tamanio ++ ] = '\n';
        }
  
        // Mostramos la salida
        System.out.print( new String( salida, 0, tamanio ) );
    }
 
    public static String invertir( long N )
    {
        // Verificamos si el numero de filas es par
        if( (N&1)==0)
            return ( N >> 1 ) * ( N + 1 )/3 + "";
        else
            return ( ( N + 1 ) >> 1 ) * N/3 + "";
    }
}

1 comentario: