/* Subject: Contest submission for problem #1, file 1.java */ /* jeffpast@imail.EECS.Berkeley.EDU */ /* Thu Sep 11 11:56:21 PDT 2003 */ /*___CONTEST_SUBMISSION___ jeffpast 1 */ /* * P1.java * * Created on September 7, 2003, 9:45 PM */ import java.util.*; import java.io.*; /** * * @author Jeff */ class P1 { /** Creates a new instance of P1 */ public P1() { } /** * @param args the command line arguments */ public static void main(String[] args) throws IOException { java.io.LineNumberReader r = new java.io.LineNumberReader(new java.io.InputStreamReader(System.in)); //System.out.print( r.readLine() ); String s; int size; char[][] matrix; Hashtable counts; //Outer loop reads matrix dimension while ( (s = r.readLine()) != null){ if (Integer.valueOf(s.trim()).intValue() == 0){ System.exit(0); return; } size = Integer.valueOf(s.trim()).intValue(); matrix = new char[size][size]; counts = new Hashtable(); //read in matrix for (int i = 0; i < size; i++) { s = r.readLine(); for (int j = 0; j < size; j++){ matrix[i][j] = s.charAt(j); counts.put(new Character(s.charAt(j)), new Integer(0)); } } //4 different views of the matrix (original + 3 rotations) int counter = 0; for (int rt = 0; rt < 4; rt++){ for (int x = 0; x < size; x++){ for (int y = 0; y < size; y++){ counter++; CountTriangles(matrix,x,y,counts); } } /* *System.out.println("-----"); for (int a = 0; a < size; a++){ for (int b = 0; b < size; b++) System.out.print(matrix[a][b]); System.out.println(); } */ matrix = Rotate(matrix); } int total = 0; Enumeration enum = counts.elements(); while (enum.hasMoreElements()) total += ((Integer)enum.nextElement()).intValue(); TreeSet l = new TreeSet(counts.keySet()); Iterator i = l.iterator(); System.out.print("(" + total + ")"); while (i.hasNext()){ Character c = (Character)i.next(); System.out.print( " " + ((Integer)counts.get(c)).intValue()); System.out.print( " " + c.toString()); } System.out.println(); } } public static void CountTriangles (char[][] matrix, int x, int y, Hashtable counts){ int size = matrix.length; int count; //enumerate all two-legs aligned possible triangles for (int ts = 2; ts <= Math.min((size-x),(size-y));ts++){ char firstChar = matrix[y][x]; boolean match = true; for (int i = ts; i > 0; i--){ for (int j = 0; j < i; j++){ if (firstChar != matrix[y + (ts-i)][x + j]) match = false; } } if (match){ count = ((Integer)counts.get(new Character(firstChar))).intValue(); counts.put(new Character(firstChar),new Integer(count+1)); } } //get the weird triangles now (ts is wt height) for (int ts = 3; ts <= (size-y) && ( (ts/2)+x < size ); ts += 2){ char firstChar = matrix[y][x]; boolean match = true; for (int i = 0; i < ts; i++){ for (int j = 0; j < wtw(i,ts); j++){ if (firstChar != matrix[y+i][x+j]) match = false; } } if (match){ count = ((Integer)counts.get(new Character(firstChar))).intValue(); counts.put(new Character(firstChar),new Integer(count+1)); } } } //retrieves the weird triange width at offset y, given a height. private static int wtw (int y, int height){ if (y == height/2) return (height/2)+1; else if (y < height/2) return y+1; else return height-y; } //Rotates a matrix. public static char[][] Rotate(char[][] matrix){ char[][] result = null; int size = matrix.length; result = new char[size][size]; for (int i = 0; i < size; i++){ for (int j = 0; j < size; j++){ result[j][size-i-1] = matrix[i][j]; } } return result; } public char[][] FlipX(char[][] matrix){ char[][] result = null; int size = matrix.length; try { result = (char[][])matrix.clone(); } catch (Exception e) { } for (int i = 0; i < size; i++){ for (int j = 0; j < size; j++){ result[i][size-j-1] = matrix[i][j]; } } return result; } public char[][] FlipY(char[][] matrix){ char[][] result = null; int size = matrix.length; try { result = (char[][])matrix.clone(); } catch (Exception e) { } for (int i = 0; i < size; i++){ for (int j = 0; j < size; j++){ result[size-i-1][j] = matrix[i][j]; } } return result; } }