viernes, 19 de septiembre de 2008

Rotating Rings






Any square grid can be viewed as one or more rings, one inside the other. For example, as shown in figure (a), a 5 * 5 grid is made of three rings, numbered 1,2 and 3 (from outside to inside.) A square grid of size N is said to be sorted, if it includes the values from 1 to N2 in a row-major order, as shown in figure (b) for N = 4. We would like to determine if a given square grid can be sorted by only rotating its rings. For example, the grid in figure (c) can be sorted by rotating the first ring two places counter-clockwise, and rotating the second ring one place in the clockwise direction.
Input
Your program will be tested on one or more test cases. The first input line of a test case is an integer N which is the size of the grid. N input lines will follow, each line made of N integer values specifying the values in the grid in a row-major order. Note than 0 < N ≤ 1, 000 and grid values are natural numbers less than or equal to 1,000,000.

The end of the test cases is identified with a dummy test case with N = 0.
Output
For each test case, output the result on a single line using the following format:

k._result

Where k is the test case number (starting at 1,) _ is a single space, and result is "YES" or "NO" (without the double quotes.)
Sample Input

4
9 5 1 2
13 7 11 3
14 6 10 4
15 16 12 8
3
1 2 3
5 6 7
8 9 4
0

Sample Output

1. YES
2. NO



SOLUCION



import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
*
* @author Luis Carlos
*/
public class rings {

private BufferedReader bf = null;

public rings() {
}

public static void main(String arg[]) {
rings e = new rings();
try {
File f = new File("C:/Users/Luis Carlos/Documents/NetBeansProjects/Maraton/src/rings.in");
e.bf = new BufferedReader(new FileReader(f));
String orden = e.bf.readLine();
int numeroLinea = 1;
while (orden != null && !orden.equals("0")) {
int[][] matriz = new int[Integer.parseInt(orden)][Integer.parseInt(orden)];
for (int i = 0; i < Integer.parseInt(orden); i++) {
String[] sp = e.bf.readLine().split(" ");
for (int j = 0; j < Integer.parseInt(orden); j++) {
matriz[i][j] = Integer.parseInt(sp[j]);
}
}
if (e.isRotatingRing(e.generarAnillos(matriz, matriz.length), e.generarAnillos(null, matriz.length))) {
System.out.println(numeroLinea++ + ". YES");
} else {
System.out.println(numeroLinea++ + ". NO");
}
orden = e.bf.readLine();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}

public ArrayList<Integer>[] generarAnillos(int[][] matriz, int orden) {
ArrayList<Integer>[] anillos = null;
try {
int n = orden, numeroAnillos = (n + 1) / 2;
anillos = new ArrayList[numeroAnillos];
for (int i = 0; i < numeroAnillos; i++) {
anillos[i] = new ArrayList<Integer>();
}
for (int k = 0; k < numeroAnillos; ++k) {
for (int j = k; j < n - k; ++j) {
if (matriz == null) {
anillos[k].add(getElementoPosicion(k, j, n));
} else {
anillos[k].add(matriz[k][j]);
System.out.println("Anillo " + k + " " + matriz[k][j]);
}
}
for (int i = k + 1; i <= n - k - 2; ++i) {
if (matriz == null) {
anillos[k].add(getElementoPosicion(i, n - k - 1, n));
} else {
anillos[k].add(matriz[i][n - k - 1]);
System.out.println("Anillo " + k + " " + matriz[i][n - k - 1]);
}
}
for (int j = n - k - 1; j >= k; --j) {
if (matriz == null) {
anillos[k].add(getElementoPosicion(n - k - 1, j, n));
} else {
anillos[k].add(matriz[n - k - 1][j]);
System.out.println("Anillo " + k + " " + matriz[n - k - 1][j]);
}
}
for (int i = n - k - 2; i > k; --i) {
if (matriz == null) {
anillos[k].add(getElementoPosicion(i, k, n));
} else {
anillos[k].add(matriz[i][k]);
System.out.println("Anillo " + k + " " + matriz[i][k]);
}
}
}
if (n % 2 != 0) {
anillos[numeroAnillos - 1].remove(anillos[numeroAnillos - 1].size() - 1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return anillos;
}
}

public int getElementoPosicion(int i, int j, int n) {
return i * n + j + 1;
}

public boolean isRotatingRing(ArrayList<Integer>[] real, ArrayList<Integer>[] referencia) {
boolean rotatingRing = true;
for (int i = 0; i < referencia.length; i++) {
ArrayList<Integer> arrayList = referencia[i];
ArrayList<Integer> auxiliarComparacion = new ArrayList<Integer>();
if (real[i].contains(arrayList.get(0))) {
auxiliarComparacion.addAll(real[i].subList(real[i].indexOf(arrayList.get(0)), real[i].size()));
auxiliarComparacion.addAll(real[i].subList(0, real[i].indexOf(arrayList.get(0))));
if (!arrayList.equals(auxiliarComparacion)) {
rotatingRing = false;
break;
}
} else {
rotatingRing = false;
break;
}
}
return rotatingRing;
}
}

miércoles, 17 de septiembre de 2008

Electronic Document Security

The Tyrell corporation uses a state-of-the-art electronic document system that controls all aspects of document creation, viewing, editing, and distribution. Document security is handled via access control lists (ACLs). An ACL defines a set of entities that have access to the document, and for each entity defines the set of rights that it has. Entities are denoted by uppercase letters; an entity might be a single individual or an entire division. Rights are denoted by lowercase letters; examples of rights are a for append, d for delete, e for edit, and r for read.

The ACL for a document is stored along with that document, but there is also a separate ACL log stored on a separate log server. All documents start with an empty ACL, which grants no rights to anyone. Every time the ACL for a document is changed, a new entry is written to the log. An entry is of the form ExR, where E is a nonempty set of entities, R is a nonempty set of rights, and x is either "+", "–", or "=". Entry E+R says to grant all the rights in R to all the entities in E, entry ER says to remove all the rights in R from all the entities in E, and entry E=R says that all the entities in E have exactly the rights in R and no others. An entry might be redundant in the sense that it grants an entity a right it already has and/or denies an entity a right that it doesn't have. A log is simply a list of entries separated by commas, ordered chronologically from oldest to most recent. Entries are cumulative, with newer entries taking precedence over older entries if there is a conflict.

Periodically the Tyrell corporation will run a security check by using the logs to compute the current ACL for each document and then comparing it with the ACL actually stored with the document. A mismatch indicates a security breach. Your job is to write a program that, given an ACL log, computes the current ACL.

Input: The input consists of one or more ACL logs, each 3–79 characters long and on a line by itself, followed by a line containing only "#" that signals the end of the input. Logs will be in the format defined above and will not contain any whitespace.

Output: For each log, output a single line containing the log number (logs are numbered sequentially starting with one), then a colon, then the current ACL in the format shown below. Note that (1) spaces do not appear in the output; (2) entities are listed in alphabetical order; (3) the rights for an entity are listed in alphabetical order; (4) entities with no current rights are not listed (even if they appeared in a log entry), so it's possible that an ACL will be empty; and (5) if two or more consecutive entities have exactly the same rights, those rights are only output once, after the list of entities.

Example input: Example output:
MC-p,SC+c
YB=rde,B-dq,AYM+e
GQ+tju,GH-ju,AQ-z,Q=t,QG-t
JBL=fwa,H+wf,LD-fz,BJ-a,P=aw
#
1:CSc
2:AeBerMeYder
3:
4:BHJfwLPaw


Solucion: eds.java



import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

public class eds {

private BufferedReader bf = null;

public eds() {
}

public static void main(String arg[]) {
eds e = new eds();
try {
File f = new File("eds.in");
e.bf = new BufferedReader(new FileReader(f));
String linea = e.bf.readLine();
int numeroLinea = 0;
while (linea != null && !linea.equals("#")) {
Map<String, String> permisos = new LinkedHashMap<String, String>();
String[] sp = linea.split(",");
for (int i = 0; i < sp.length; i++) {
if (sp[i].indexOf("-") >= 0) {
String[] prs = sp[i].split("-");
for (int j = 0; j < prs[0].length(); j++) {
permisos.put(String.valueOf(prs[0].charAt(j)), e.retirarPermisos((String) permisos.get(String.valueOf(prs[0].charAt(j))), prs[1]));
}
}
if (sp[i].indexOf("+") >= 0) {
String[] prs = new String[2];
prs[0] = sp[i].substring(0, sp[i].indexOf("+"));
prs[1] = sp[i].substring(sp[i].indexOf("+") + 1);
for (int j = 0; j < prs[0].length(); j++) {
permisos.put(String.valueOf(prs[0].charAt(j)), e.agregarPermisos((String) permisos.get(String.valueOf(prs[0].charAt(j))), prs[1]));
}
}
if (sp[i].indexOf("=") >= 0) {
String[] prs = sp[i].split("=");
for (int j = 0; j < prs[0].length(); j++) {
permisos.put(String.valueOf(prs[0].charAt(j)), prs[1]);
}
}
}
System.out.println((numeroLinea++ + 1) + ":" + e.listadoEntidadesPermisos(permisos).replace("null", ""));
linea = e.bf.readLine();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}

public String getOrdenada(String cadena) {
String res = "";
char[] sb = cadena.toCharArray();
for (int k = 0; k < sb.length; k++) {
for (int i = 0; i < sb.length - 1; i++) {
if (sb[i] > sb[i + 1]) {
char tmp = sb[i];
sb[i] = sb[i + 1];
sb[i + 1] = tmp;
}
}
}
for (int i = 0; i < sb.length; i++) {
res += sb[i];
}
return res;
}

public String retirarPermisos(String cadena, String permisos) {
String cadenaRetorno = cadena;
if (cadena != null) {
for (int i = 0; i < permisos.length(); i++) {
cadenaRetorno = cadenaRetorno.replace(String.valueOf(permisos.charAt(i)), "");
}
} else {
cadenaRetorno = "";
}
return cadenaRetorno;
}

public String agregarPermisos(String cadena, String permisos) {
String cadenaRetorno = cadena;
if (cadena != null) {
for (int i = 0; i < permisos.length(); i++) {
if (!cadenaRetorno.contains(String.valueOf(permisos.charAt(i)))) {
cadenaRetorno += String.valueOf(permisos.charAt(i));
}
}
} else {
cadenaRetorno = permisos;
}
return cadenaRetorno;
}

public String listadoEntidadesPermisos(Map<String, String> permisos) {
String permisosRetorno = "";
String[] prm = new String[permisos.keySet().size()];
permisos.keySet().toArray(prm);
ordenarArray(prm);
String permisoAnterior = "";
ArrayList<Mapeo> maps = new ArrayList<Mapeo>();
for (int i = 0; i < prm.length; i++) {
if (!permisos.get(prm[i]).equals("")) {
if (getOrdenada(permisoAnterior).equals(getOrdenada(permisos.get(prm[i])))) {
Mapeo mp = maps.get(maps.size() - 1);
mp.setEntidades(mp.getEntidades().append(prm[i]));
} else {
Mapeo mp = new Mapeo();
mp.setPermisos(permisos.get(prm[i]));
mp.setEntidades(new StringBuffer(prm[i]));
maps.add(mp);
permisoAnterior = permisos.get(prm[i]);
}
}
}
for (Mapeo aux : maps) {
permisosRetorno += aux.getEntidades().toString() + getOrdenada(aux.getPermisos());
}
return permisosRetorno;
}

public void ordenarArray(String[] prm) {
String tmp;
for (int k = 0; k < prm.length; k++) {
for (int i = 0; i < prm.length - 1; i++) {
if (prm[i].compareTo(prm[i + 1]) > 0) {
tmp = prm[i];
prm[i] = prm[i + 1];
prm[i + 1] = tmp;
}
}
}

}
}

class Mapeo {

private StringBuffer entidades;
private String permisos;

public Mapeo() {
}

public Mapeo(StringBuffer entidades, String permisos) {
this.entidades = entidades;
this.permisos = permisos;
}

public StringBuffer getEntidades() {
return entidades;
}

public void setEntidades(StringBuffer entidades) {
this.entidades = entidades;
}

public String getPermisos() {
return permisos;
}

public void setPermisos(String permisos) {
this.permisos = permisos;
}
}

jueves, 4 de septiembre de 2008

100 The 3n + 1 problem

Background

Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem you will be analyzing a property of an algorithm whose classification is not known for all possible inputs.

The Problem
Consider the following algorithm:
1. input n
2. print n
3. if n = 1 then STOP
4. if n is odd then
5. else
6. GOTO 2

Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)
Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.
For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.


The Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
You can assume that no operation overflows a 32-bit integer.


The Output
For each pair of input integers i and j you should output i, j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).

Sample Input
1 10
100 200
201 210
900 1000


Sample Output
1 10 20
100 200 125
201 210 89
900 1000 174

Referencia http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=36



SOLUCIÓN POSIBLE (este codigo da Wrong answer)

import java.io.*;

/**
*
* @author dthomas
*/
class Main {

public static int longitud;
public static int mayor;

public static int longitudNumero(int num) {
if (num == 0) {
return 0;
}
int contador = 1;
while (num != 1) {
if (num % 2 != 0) {
num = num * 3 + 1;
} else {
num = num / 2;
}
contador = contador + 1;
}
return contador;
}

public static int MaxLongitud(int i, int j) {
int inf, sup;
mayor = 0;
if (i > j) {
inf = j;
sup = i;
} else {
sup = j;
inf = i;
}
for (int k = inf; k <= sup; k++) {
int lon = longitudNumero(k);
if (lon > mayor) {
mayor = lon;
}
}
return mayor;
}

public static void main(String a[]) {
FileReader fr;
try {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String linea = bf.readLine();
String valores[];
int num1, num2;
while ((linea != null)) {
valores = linea.split(" ");
if (valores.length == 2) {
num1 = Integer.parseInt(valores[0]);
num2 = Integer.parseInt(valores[1]);
System.out.println(num1 + " " + num2 + " " + MaxLongitud(num1, num2));
}
linea = bf.readLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}