AtCoder157振り返り
2020/3/1(日) に3回目のAtCoderに挑戦
結果としては遺憾の2完。。。ABは20分でしたがCでドツボにはまりました。
今回の内容を改めて振り返っていきます。
■解決
第1問:Duplex Printing
この問題は両面印刷に必要な部数を求めるプログラムです。
頭では秒で解けましたが若干コーディングに手間取りました。
■回答コード
- import java.util.Scanner;
- //Distinct or Not
- public class Main {
- public static void main(String args){
- Scanner sc = new Scanner(System.in);
- int n = sc.nextInt();
- int adj = n %2;
- System.out.println(n/2 + adj);
- }
- }
第2問
2問目は3×3のビンゴ問題でした。
これはさほど複雑ではないですが、今までのAB問題に比べるとややコーディングの量が多くなりました。
単純に3×3にした後に、ビンゴした数値を0に置換して最後にチェックしています。
解答では30行程度でしたのでもっと短くできるはずですね。。。
■回答コード
- import java.util.Scanner;
- //Distinct or Not
- public class Main {
- public static void main(String args){
- Scanner sc = new Scanner(System.in);
- int bingo = new int[3][3];
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- bingo[i][j] = sc.nextInt();
- }
- }
- int max = sc.nextInt();
- for(int x = 0; x < max; x++) {
- int num = sc.nextInt();
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- if(bingo[i][j] == num) {
- bingo[i][j] = 0;
- }
- }
- }
- }
- //正解チェック
- int cnt = 0;
- boolean flg = false;
- //横チェック
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- if(bingo[i][j] == 0) {
- cnt++;
- }
- if(cnt == 3) {
- flg = true;
- }
- }
- cnt = 0;
- }
- //縦チェック
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- if(bingo[j][i] == 0) {
- cnt++;
- }
- if(cnt == 3) {
- flg = true;
- }
- }
- cnt = 0;
- }
- //斜めチェック
- if(bingo[0][0] == 0) cnt++;
- if(bingo[1][1] == 0) cnt++;
- if(bingo[2][2] == 0) cnt++;
- if(cnt == 3) flg = true;
- cnt = 0;
- if(bingo[0][2] == 0) cnt++;
- if(bingo[1][1] == 0) cnt++;
- if(bingo[2][0] == 0) cnt++;
- if(cnt == 3) flg = true;
- if(flg) {
- System.out.println("Yes");
- } else {
- System.out.println("No");
- }
- }
- }
■未解決
第3問
第3問ですがやや複雑でした。がそこまで難しい内容ではないです。
1~3桁に対して、各桁ごとの値が提案されるのでその値の条件に合致する候補の最小値を設定するというものです。
そして、条件を満たす値がなければ-1を返します。
"最小値を設定する"という点でドツボにはまったのですが、例えば
引数が以下の場合
3 1
2 4
3 9
3桁の値に対して、2桁目が4、3桁目が9となります。
x49という値が候補に挙がりますが、先頭1桁目が未確定なので最小値の0を設定して
049が答え、、、ではないです。
先頭が0という値はあり得ないとしているので、この場合の答えは194が正解です。
私はこのロジックが考慮されていなかったがために時間切れでした。。。(解答見直したときやっちまった。。。と思いましたね。)
■回答コード
- import java.util.Scanner;
- public class Main {
- public static void main(String args) {
- // TODO 自動生成されたメソッド・スタブ
- Scanner sc = new Scanner(System.in);
- int N = sc.nextInt();
- int M = sc.nextInt();
- boolean flgM = new boolean[N];
- int[] intN = new int[N];
- boolean NG = false;
- for(int i = 0; i < M; i++) {
- int s = sc.nextInt();
- int c = sc.nextInt();
- if(flgM[s-1] == false || intN[s-1] == c) {
- intN[s-1] = c;
- flgM[s-1] = true;
- } else {
- NG = true;
- }
- }
- if(NG) {
- System.out.println(-1);
- } else {
- int result = 0;
- int kakeru = 1;
- for(int i = N-1; i >= 0; i--) {
- result = result + intN[i] * kakeru;
- if(N > 1 && i == 0 && flgM[i] == false) result = result + 1 * kakeru;
- kakeru = kakeru * 10;
- }
- if(String.valueOf(result).length() != N) {
- result = -1;
- }
- System.out.println(result);
- }
- }
- }
■未受講
第4問
人1~Nの友達候補がそれぞれ何人いるかを求めるアルゴリズムです。
パット見て解けなくはなさそうですが、、、ブロック関係がよくわからないです。
DFS(深さ優先探索)というものを使えば解けるとのこと
今度勉強しておこう。。。
第5問
引数として渡されるクエリを順に処理していく処理ですが、
あまり難しくないように思えますがどうでしょうか?
クエリはType1, Type2に分かれますがType1は並行二分探索木で解けるとのこと
Type2はlower_bound関数(探索したいKey以上のイテレータを返す)で行けるらしい。。。
ここら辺のアルゴリズムもまだ勉強しないとですね。
第6問
( ^ω^)・・・???
数か月後にはここら辺もわかるのでしょうか。。。
参考
AtCoder157解説