Problem:
問題 3

　ある工場では，各営業所から製品生産の注文を受けている．
前日の注文をまとめて，各製品の生産合計を求めたい．

　入力ファイルの１行目には注文データの数 n が書いてあり，
続く n 行には製品名と注文数が空白で区切られて書いてある．
製品名は5文字以内の英大文字で書かれている．
注文データには同じ製品が含まれていることもあり，順序はバラバラである．

　この注文データの中に現れる同じ製品の注文数を合計し，
出力ファイルに製品名と合計を空白を区切り文字として出力しなさい．
ただし，製品名に次の順序を付けて，その順で出力すること．

　順序：文字の長さの小さい順に，同じ長さのときは，前から比べて
最初に異なる文字のアルファベット順とする．

入力データにおける製品数，注文数とその合計のどれも106以下である．

　出力ファイルにおいては，
出力の最後の行にも改行コードを入れること．

入出力例

入力例1

5
A 20
B 20
A 20
AB 10
Z 10

出力例1

A 40
B 20
Z 10
AB 10

入力例2

5
AAA 20
ABA 20
AAA 20
AAB 20
AAA 20

出力例2

AAA 60
AAB 20
ABA 20

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in JAVA (judge verdict: Accepted)


import java.io.IOException;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.TreeMap;

public class Main {

	public static void main(String[] args) throws IOException {

		new Main().run();
	}

	private void run() throws IOException {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		Map<String, Integer> memo = new TreeMap<String, Integer>(
				new Comparator<String>() {

					@Override
					public int compare(String o1, String o2) {
						if (o1.length() == o2.length())
							return o1.compareTo(o2);
						return o1.length() - o2.length();
					}
				});
		for (int i = 0; i < n; i++) {
			String s = scanner.next();
			int a = scanner.nextInt();
			if (memo.containsKey(s))
				memo.put(s, memo.get(s) + a);
			else
				memo.put(s, a);
		}
		for (Entry<String, Integer> entry : memo.entrySet()) {
			System.out.println(entry.getKey() + " " + entry.getValue());
		}
	}
}