【Java】AtCoderのABC-191に参加しました。

こんばんは。

2021/2/6に、AtCoderのABC-191に参加しました。
レートは以下の通りとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/b6a44fa5-d03e-736b-30fd-879d838ad4f3.png)


https://atcoder.jp/users/ishikawaryou

残り10分でC問題を突破しました。
嬉しいのですが、安定して結果が出ないうちはぬか喜びは禁物ですね・・。
レートは71→173に更新！おお、結構上がったな。

A問題・B問題は合計10分ということで、スピードは上がっています。ただ、てことは、C問題は80分かかったのか・・。

###A問題

高橋くんが投げるボールの速度がV（m/s）。
T秒からS秒の間は消えている。
高橋くんからバッターまでの距離はD。この間バッターはボールを打てない。
さてボールは打てるかどうか？
T秒からS秒の間に、バッターまでの距離に到達しないかを調べる処理で、非常にシンプルなプログラムになりました。

```java
import java.util.Scanner;
import java.util.ArrayList;

public class Main{
public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  int v = sc.nextInt();
  int t = sc.nextInt();
  int s = sc.nextInt();
  int d = sc.nextInt();
  if(d<v*t||d>v*s){
    System.out.println("Yes");
  }else{
    System.out.println("No");
  }
}
}
```


###B問題
N個の配列aを用意する。
X以外の要素を順番に出力する。

n x
a1....an

思い返せば、B問題としても易しい部類なのかな？

```java
import java.util.Scanner;
import java.util.ArrayList;

public class Main{
public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  int n = sc.nextInt();
  int x = sc.nextInt();
  int a[] = new int[n];
  for(int i=0;i<n;i++){
   a[i] = sc.nextInt();
  }
  
  for(int i=0;i<n;i++){
    if(a[i]!=x){
      System.out.println(a[i]);
    } 
  }
}
}
```

###C問題
H行W列のマス目があり、マス目には"#"（黒）、"."（白）が入っている。
"#"を使って多角形が描かれているイメージだとすると、何角形になるか？
....
.##.
....
→4角形

.....
...#.
..##.
.###.
.....
→8角形

C問題は、いつも読んだ瞬間、頭が真っ白になります・・。
落ち着いて問題文を読んでいく事が大事ですね。

・まず考えたのは、「どれだけ白に面しているかで、辺の数（角の数）がぼんやり分かる」でした。なので、白に面している辺の数を数えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/e0683603-852c-11f8-7f83-35934dd1719d.png)
この場合は12個。
数え方は単純で、1つずつのマスにおいて、前後左右で白のマスがないかチェックしカウントします。

・そのあと、無駄に数えている分を取り除くことにしました。ここではまりましたが・・。
無駄に数えているのは、以下赤字の部分ですよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/6a2437d3-24ef-ed91-74cd-26ed9273c5ea.png)

こいつを除きたいので、どうロジックに落とすか？

いっこずつ見ていくと、
①右側が黒かったら？
チェックしているマス、および右隣のマスが黒かったら？
それは辺が連続している可能性があります。
連続しているかをチェックするためには、「辺がまっすぐになっているか」です。
なので下側、および右下のマスが白いかどうかをチェックしました。

②上側が黒かったら？
同じ要領で、右側、および右上が白いかどうかをチェックしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/27705062-b84a-3a36-a9dd-776a602d29e5.png)


その後、①上と右上、②には左と左上のチェックが必要な事に気付き修正。
こうすると、無駄に数えているのは8個。
12-8=4　で、4角形になります。
このロジックが、ある程度複雑なパターンで試してOKそうだったのでこれで実行しました。

こんなプログラムになったっす！！

```java
import java.util.Scanner;
import java.util.ArrayList;

public class Main{
public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  int h = sc.nextInt();
  int w = sc.nextInt();
  String sm[] = new String[h];
  for(int i=0;i<h;i++){
      sm[i] = sc.next();
  }
  
  String s[][] = new String[h][w];
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      s[i][j] = String.valueOf(sm[i].charAt(j));
    }
  }
  // siro to mensita hen no kazu
  int smen = 0;
  for(int i=1;i<h-1;i++){
    for(int j=1;j<w-1;j++){
      //System.out.println(s[i][j]);
      if(s[i][j].equals("#")){
//      System.out.println(" i " + i + " j " + j + " s[i][j] " + s[i][j]);
        if(s[i-1][j].equals(".")){
          smen++;
        }        
        if(s[i+1][j].equals(".")){
          smen++;
        }        
        if(s[i][j-1].equals(".")){
          smen++;
        }        
        if(s[i][j+1].equals(".")){
          smen++;
        }        
      }
    }
  }
//  siro chk
  int ncnt = 0;
    for(int i=1;i<h-1;i++){
    for(int j=1;j<w-1;j++){
      //System.out.println(s[i][j]);
      if(s[i][j].equals("#")){
        //if(s[i+1][j].equals("#")&&((s[i][j-1].equals(".")&&s[i+1][j-1].equals("."))||(s[i][j+1].equals(".")&&s[i+1][j+1].equals("."))){
        if(s[i+1][j].equals("#")){
            //if((s[i][j-1].equals(".")&&s[i+1][j-1].equals("."))||(s[i][j+1].equals(".")&&s[i+1][j+1].equals("."))){
            //  ncnt++;
            //}
            if((s[i][j-1].equals(".")&&s[i+1][j-1].equals("."))){
      //System.out.println("a");
              ncnt++;
            }
            if((s[i][j+1].equals(".")&&s[i+1][j+1].equals("."))){
      //System.out.println("b");
              ncnt++;
            }
        }        
        if(s[i][j+1].equals("#")){
            //if((s[i+1][j].equals(".")&&s[i+1][j+1].equals("."))||(s[i-1][j].equals(".")&&s[i-1][j+1].equals("."))){
            //  ncnt++;
            //}
            if((s[i+1][j].equals(".")&&s[i+1][j+1].equals("."))){
              ncnt++;
            }
            if((s[i-1][j].equals(".")&&s[i-1][j+1].equals("."))){
              ncnt++;
            }
        }        
//        if(s[i][j+1].equals("#")&&(s[i+1][j].equals(".")&&s[i+1][j+1].equals("."))||){
//          ncnt++;
//        }        
      }
    }
  }
//  siro chk

//
      //System.out.println(smen);
      //System.out.println(ncnt);
      System.out.println(smen-ncnt);
  
  
}
}
```
苦労の跡が見えていて恥ずかしいですが・・。

###感想
今後やっておきたいのは、自分の「武器をまとめておくこと」です。
・配列をソートするためにはどうすればよいか？
・属性変換のやり方は？（int⇔string、char⇔int等）
これを引き出しとして用意しておけば、対応できるケースが増える（頭真っ白になる事が減る）と思っています。

前回「あと3回でレート150」としていましたが、今回もうクリアしてしまいました。
レートの変動はよく分からないですね。

これからもコツコツ取り組んで、茶色を目指したいと思います！
同じく灰色レベルで頑張っている方、お互い頑張りましょう！