AOJ1211 Trapezoids

問題リンク Trapezoids

  • 概要

台形が'*'で描かれた図が与えられる。描かれている台形の面積とその個数を答えよ。
台形は水平方向の辺は必ず平行で、垂直方向は水平方向の辺に対して斜めに45度か直角である。
ある2つの台形が隣接していることはない。つまり、台形の全ての'*'の周り8マスに他の台形の'*'が無いことを指す。

  • 解法

左上から探索していき、'*'を見つけたら、その台形をなぞるように探索していきます。台形の面積は水平方向の2辺と高さから求められます。

  • ソース
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;

//Trapezoids
public class AOJ1211 {

	int h;
	char[][] map;
	int[] move = {-1,0,1};

	void run(){
		Scanner sc = new Scanner(System.in);
		boolean f = true;
		while(true){
			h = sc.nextInt();
			if(h==0)break;
			if(!f)System.out.println("----------");
			f = false;
			Map<Integer, Integer> ans = new HashMap<Integer, Integer>();
			map = new char[h][];
			sc.nextLine();
			for(int i=0;i<h;i++)map[i]=sc.nextLine().toCharArray();
			for(int i=0;i<h;i++){
				for(int j=0;j<map[i].length;j++){
					if(map[i][j]!='*')continue;
					int a = 1;
					map[i][j] = ' ';
					int k = j+1;
					while(k<map[i].length&&map[i][k]=='*'){
						map[i][k++] = ' ';
						a++;
					}
					k--;
					int height = 1;
					int b = 1;
					for(int d=0;d<3;d++){
						int w = j+move[d];
						if(0<=w&&w<map[i+1].length&&map[i+1][w]=='*'){
							int y = i+1;
							while(y<h&&0<=w&&w<map[y].length&&map[y][w]=='*'){
								height++;
								map[y][w] = ' ';
								y++;
								w += move[d];
							}
							y--;
							w-=move[d];
							w++;
							while(w<map[y].length&&map[y][w]=='*'){
								b++;
								map[y][w] = ' ';
								w++;
							}
							w--;
							int dir = w<k?0:w==k?1:2;
							y = i+1;
							w = k + move[dir];
							while(w<map[y].length&&y<h&&map[y][w]=='*'){
								map[y][w] = ' ';
								y++;
								w+=move[dir];
							}
							break;
						}
					}
					int area = (a+b)*height/2;
					if(ans.containsKey(area)){
						ans.put(area, ans.get(area)+1);
					}
					else{
						ans.put(area, 1);
					}
				}
			}
			PriorityQueue<Integer> q = new PriorityQueue<Integer>();
			for(Integer i:ans.keySet())q.add(i);
			while(!q.isEmpty()){
				int area = q.poll();
				System.out.println(area+" "+ans.get(area));
			}
		}
	}

	public static void main(String[] args) {
		new AOJ1211().run();
	}
}