ABC003の解法[Java]

## はじめに
ABC002に引き続き、ABC003を解いて見ました。ただ、D問題はちょっと解法が思いつかなかったので後日解いてみようと思います。

では、ACが取れたコードを解説していきます。

## A - AtCoder社の給料
問題文は[こちら](https://atcoder.jp/contests/abc003/tasks/abc003_1)

平均値を求める式を考えると、
```math
\dfrac{1}{N}\times\sum_{i=1}^N(10000\times i)=\dfrac{10000}{N}\times\dfrac{1}{2}N(N+1)=10000\times\dfrac{N+1}{2}
```
となりますから、最後の式をコードに落とし込みましょう。念のためキャスト演算子でlong型にしてはいますが、最大値はN=100なので、$10000\times101=1.01\times10^6$であることを考えるとint型のままでも良いです。
```A.java
import java.util.*;
class Main{
  public static void main(String[] args){
    Scanner sc = new Scanner(System.in);
    //値の受け取り
    int N = sc.nextInt();
    //数式の計算結果を出力
    System.out.println((long)(N+1)*10000/2);
  }
}
```
数式にさえ落とし込めば簡単ですね。まぁN≦100なら普通にforループで足し算していって10000かけてNで割っても計算しきれますが･･･。

## B - AtCoderトランプ
問題文は[こちら](https://atcoder.jp/contests/abc003/tasks/abc003_2)

ちょっと条件文がネストしまくって見にくいですが、負ける時の条件を書き出して負けるならその時点でプログラムを終了させるようにしてやればいいです。
```B.java
import java.util.*;
class Main{
  public static void main(String[] args){
    Scanner sc = new Scanner(System.in);
    //文字列を分解して一文字ずつString型配列に格納
    String[] str1 = sc.next().split("");
    String[] str2 = sc.next().split("");
    //一文字ずつforループで検証
    for(int i=0;i<str1.length;i++){
      //同じ文字でない？
      if(!(str1[i].equals(str2[i]))){
        //S側は"@"か？
        if(str1[i].equals("@")){
          //T側は"@"で変換できない文字か？
          if(!(str2[i].equals("a")||
             str2[i].equals("t")||
             str2[i].equals("c")||
             str2[i].equals("o")||
             str2[i].equals("d")||
             str2[i].equals("e")||
             str2[i].equals("r")
            )){
             //変換できないなら負け
             System.out.println("You will lose");
             System.exit(0);
          }
        }
        //T側は"@"か？
        else if(str2[i].equals("@")){
          //S側は"@"で変換できない文字か？
          if(!(str1[i].equals("a")||
             str1[i].equals("t")||
             str1[i].equals("c")||
             str1[i].equals("o")||
             str1[i].equals("d")||
             str1[i].equals("e")||
             str1[i].equals("r")
            )){
             //変換できないなら負け
             System.out.println("You will lose");
             System.exit(0);
          }
        }
        //どちらも"@"でない=負け
        else{
          System.out.println("You will lose");
          System.exit(0);
        }
      }
    }
    //全部等しいor変換可能なら勝ち(forループを抜け出せるなら勝ち)
    System.out.println("You can win");
  }
}
```
@がなかなかに厄介でした。条件もっと良い書き方ありそう･･･。

## C - AtCoderプログラミング講座
問題文は[こちら](https://atcoder.jp/contests/abc003/tasks/abc003_3)

N≦100なので全探索しても良さそうな気はしますが、ちょっと考えてみると、最大値Mは以下の式で求められます(Rは昇順並べ替え済み)。
```math
M=\sum_{i=N-K}^{N-1}\dfrac{R[i]}{2^{N-i}}
```
数式で書くとちょっとわかりにくいですが、要は昇順に並べ替えたときのN-K+1番目のレートの動画から順に見ていけば最大値がとれることを表しています。
では、コードに起こしていきましょう。
```C.java
import java.util.*;
class Main{
  public static void main(String[] arg){
    Scanner sc = new Scanner(System.in);
    //値を受け取る
    int N = sc.nextInt();
    int K = sc.nextInt();
    //レートを受け取る為の配列の準備
    int[] R = new int[N];
    //forループで取得
    for(int i=0;i<N;i++){
      R[i] = sc.nextInt();
    }
    //昇順並べ替え
    Arrays.sort(R);
    //答え用変数の準備
    double answer = 0;
    //N-K+1番目のレートの動画から順に視聴
    for(int i=N-K;i<N;i++){
      answer = (answer + R[i])/2.0;
    }
    //答え出力
    System.out.println(answer);
  }
}
```
案外簡単だったなと感じます。こんな感じで数式が思いつけば、の話ですが･･･。

## D - AtCoder社の冬
問題文は[こちら](https://atcoder.jp/contests/abc003/tasks/abc003_4)

ACが取れ次第更新予定

## 総評
A：単純に解いても数式で解いてもACが取れる、いろんなアプローチができる面白い問題だった
B：少々条件文のネストに手こずった。ちょっと難しめ？
C：出力例から推測できた。良かった･･･。
D:

この辺あたりからだいぶキツいですね･･･。