ACMの過去問解いてみた!!(2)
前回に引き続き、ACMの過去問を、、、。もちろんJavaです。
ProblemA 等しい合計点
太郎と花子がカードを交換する問題です。
とりあえず入力の処理から。
public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(Q.class .getResourceAsStream("input.txt"))); String line = null; while ((line = br.readLine()) != null) {
ここまでで、ファイルの入ったインプットをとりあえず一行ずつ読み込みます。
String[] str = line.split(" "); int n = Integer.parseInt(str[0]); // 太郎のカードの枚数 int m = Integer.parseInt(str[1]); // 花子のカードの枚数 int numTaro[] = new int[n]; // 太郎の持っているカードの点数 int numHanako[] = new int[m]; // 花子の持っているカードの点数 int cNum[] = { 100, 100 }; //交換が等しくなるカードの組み合わせ
line.splitでそれぞれのカードの枚数を読み込みます。
それから点数を入れる用の変数を作り,出力用の答えを入れる変数を作ります。これには,問題文に”合計を等しくするようなカードの交換の方法が複数ある場合は, 交換するカードの点数の和が最小となるものを出力すること.”とあるので、とりあえず一番大きい100を入れておきます。
for (int i = 0; i < n + m; i++) { line = br.readLine(); if (i < n) { numTaro[i] = Integer.parseInt(line); } else { numHanako[i - n] = Integer.parseInt(line); } } if (n == 0 && m == 0) {//終了条件 break; }
カードの枚数の分だけそれぞれの配列に入れていきます。
終了条件もここに記述しておきます。
for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { int changeCard = 0; //カード交換用の変数 changeCard = numTaro[i]; numTaro[i] = numHanako[j]; numHanako[j] = changeCard;
いよいよ本題です。
一つづつカードを交換します。
if (sumArray(numTaro) == sumArray(numHanako)) { //sumArray:合計用のメソッド if (numHanako[j] + numTaro[i] < cNum[0] + cNum[1]) { cNum[0] = numHanako[j]; cNum[1] = numTaro[i]; } } numHanako[j] = numTaro[i]; numTaro[i] = changeCard; } }
それから合計用のメソッドを呼び出し、もし"合計が等しい"かつ"今までの組み合わせの和より小さい"ならば答えを入れ替えます。
それから次の交換のためにカードをもとに戻します。この処理を全ての組み合わせで行います。
if (cNum[0] == 100 && cNum[1] == 100) { System.out.println(-1); } else { System.out.println(cNum[0] + " " + cNum[1]); cNum[0] = 100; cNum[1] = 100; } } }
最後に出力部分です。
もし100,100のままなら、交換されていないので-1を、それ以外ならカードの組み合わせを出力します。
private static int sumArray(int x[]) { int sum = 0; for (int s : x) { sum = sum + s; } return sum; } }
一応、合計用のメソッドです。
今日はこんな感じで。このくらいの問題は慣れてきた...。