Yukii

主にプログラミング(Flutter)についての記事を書いています。

AtCoderの過去問をDartで解いてみた~Part2~

本日は、@drkenさんの AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~ の第二問目をDartで解いてみました。
第二問では

  • for 文を使わない程度の全探索
  • string 型

がキーポイントになっております。

ABC 081 A - Placing Marbles

[問題]
1,2,3の番号がついた 3つのマスからなるマス目を持っています。 各マスには 0 か 1 が書かれています。
1が書かれたマスにビー玉を置く場合、ビー玉が置かれるマスがいくつあるか求めてください。

[解法]

import 'dart:io';

void main() {
  String abc = stdin.readLineSync(); // 文字列入力
  int count;
  count = 0;
  for (int i = 0; i < 3; i++) {
    if (abc[i] == "1") count++;
  }
  print(count);
}

解法としては、入力された文字列が"1"の時に、自身で定義したcountの値を一つ増やします。

ABC 095 A - Something on It

[問題]
あるラーメン店のラーメンの値段は1杯 700円ですが、トッピング(味玉、チャーシュー、ねぎ)を乗せた場合は1種類につき100円が加算されます。
ある客がラーメンを一杯注文し、店員にトッピングの希望を伝えました。
店員は注文の内容文字列Sに書きました。1文字目が o のとき客のラーメンに味玉を乗せることを、x のとき味玉を乗せないことを表します。同様に、
2文字目、3文字目はそれぞれチャーシュー、ねぎの有無を表します。
Sが入力されるとき、対応するラーメンの値段を出力するプログラムを書いてください。

[解法]

mport 'dart:io';

void main() {
  String s = stdin.readLineSync();
  int yen = 700; //ラーメンのデフォルト値を与える
  int count;
  count = 0;
  for (int i = 0; i < 3; i++) {
    if (s[i] == "o") count++;
  }
  print(count * 100 + yen);
}

解法としては、ABC 081 Aとよく似ています。入力された文字列が"1"の時に、自身で定義したcountの値を一つ増やし、ラーメンのデフォルトの値段にcountで数えた分のトッピング料金を加算します。

ABC 085 A - Already 2018

[問題]
ある書類には、その日の日付を yyyy/mm/dd という形式で書き込む欄があります。この書類を書き終えたあと、筆者は日付欄の先頭に誤って2017と書いてしまっていたことに気がつきました日付欄を2018に修正して出力するプログラムを書いてください。

[解法]

import 'dart:io';

void main() {
  String s = stdin.readLineSync();
  String a;
  if (s.startsWith("2017")) {
    a = s.replaceFirst('2017', "2018");
  }
  print(a);
}

日付の形式が yyyy/mm/ddであるため、直接"2017"を"2018"に変更しても月、日に影響はない。

ABC 069 B - i18n

[問題]
"internationalization"という英単語は、"i18n"と略されることがあります。 これは、先頭文字 i と末尾文字 n の間に18文字が挟まっていることに由来します。
長さ3以上の英小文字のみからなる文字列s が与えらたとき、同様の規則によって sを略してください。

[解法]

import 'dart:io';

void main() {
  String s = stdin.readLineSync();
  String sf = s[0];
  String sl = s[s.length - 1];
  int len = s.length - 2;
  String ans = sf + len.toString() + sl;
  print(ans);
}

入力された文字列の最初の文字、文字の長さ、最後の文字を取得して、それらをつなげれば良い。

ABC 082 B - Two Anagrams

[問題]
英小文字のみからなる文字列s, tが与えられます。 あなたは、sもtも文字を好きな順に並べ替え、新しい文字列s'、t' を作ります。
このとき、辞書順で s'がt'より先に来ることができるか判定してください。

[解法]

import 'dart:io';

void main() {
  String s = stdin.readLineSync();
  String t = stdin.readLineSync();

  List ss = s.split(""); // 文字列をリストにする
  List sortS = ss..sort();
  String stringS = sortS.join(); // sortしたリストを文字列に直す
  List tt = t.split("");
  List sortT = tt..sort((b, a) => a.compareTo(b)); // 逆sortする

  String stringT = sortT.join();
  List before = [stringS, stringT]; // s'とt'がどちらが先かsortして判断する
  String before1 = stringS;
  String after1 = (before..sort())[0];
  String before2 = stringT;
  String after2 = (before..sort())[1];
  if (before1 == before2 && after1 == after2) { // s'もt'も全く同じ文字列の場合
    print("No");
  } else if (before1 != after1) { 
    print("No");
    return;
  } else if (before1 == after1) {
    print("Yes");
    return;
  }
}

before == afterという条件は使えなかったので各第一成分が同じかどうかで判断した。

まとめ

今回はABC 082Bが一番手こずりました。
次回は @drkenさんの AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~の第3問を解いて行きたいと思います。

(参考)
qiita.com
qiita.com