ABC193-B
問題「ゲーム機を買いに。販売しているのはN軒あり、店iは現在地から徒歩Ai分、販売価格Pi円、現在の在庫はXi台です。歩いて向かいあれば買えるが0.5,1.5,2.5分後に在庫が1台減る。買うことはできるか、その時の最小金額は?」
「N
A1 P1 X1
.
.
AN PN XN」
という入力ですが、これも例を見ないとわからない…例1は
「3
3 9 5
4 8 5
5 7 5」
店1に向かうと3分かかるので5台-3で着いた時2台あり9円で買えます。店2に向かうと4分かかるので5台-4で着いた時1台あり8円で買えます。店3に向かうと5分かかるので5台-5で着いた時在庫がないので買えません。答えは「8」
この問題も小さい方を求めるのでansを大きい数字にしておきます。
'use strict'
function main(input) {
input = input.split("\n");
let N = Number(input[0]);
let ans = 100100100100;
for(let i = 1; i <= N; i++) {
let [a, p, x] = input[i].split(" ").map(Number);
if(x > a && ans > p) {
ans = p;
}
}
if(ans === 100100100100) {
ans = -1;
}
console.log(ans);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
for文の条件はinput[0]のNは要らないのでlet i = 1;1からNまでループします。そろぞれを[a, p, x]に分けて、在庫がかかる時間より大きく、ansより価格が安ければ買えますので、ansがその時の価格pになります。買えなかった場合はpがansより高いことは流石にないので、x > aが成立しない・在庫がなかった時でしょう。ansは書き換えられていないのでif(ans === 100100100100)の時ans = -1;になります。
ABC192-B
問題「先頭から奇数番目の文字が全て英小文字、偶数番目が英大文字、これを“読みにくい文字列”とする。Sが読みにくい文字か判定し、”Yes”か”No”か」
例1「dIfFiCuLt」は”Yes”で、例2「eASY」は”No”になります。問題文は簡単ですが、この時点で解法が浮かばないですよね。新しいtoLowerCaseとtoUpperCaseを使い小文字にしたり大文字にしたりの操作をします。
'use strict'
function main(input) {
let items = input.trim().split("\n");
let words = items[0].split("");
let ans = "Yes";
for(let i = 0; i < words.length; i++) {
if(i % 2 === 0) {
if(words[i] !== words[i].toLowerCase()) {
ans = "No";
break;
}
} else {
if(words[i] !== words[i].toUpperCase()) {
ans = "No";
break;
}
}
}
console.log(ans);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
変換もポイントですが、console.log(items)は[ ‘dIfFiCuLt’ ]になり、console.log(words);は[ ‘d’, ‘I’, ‘f’, ‘F’, ‘i’, ‘C’, ‘u’, ‘L’, ‘t’]です。let an s= ”Yes”で準備して、1つでも違ったら”No”にして関数を終える実装です。ifで奇数番目を表すのはi % 2 ===0 最初のi=0も2で割ると余りは0になります。
例えば1番目のwords[0]はdであり、words[0].toLowerCase()は「dを小文字にしたもの」になりますのでdのまま、「!==」は出ない時に”No”にしてbreak終了なのでwords[0]が終わった時点でansは”Yes”のまま次のwords[1]のループへ移ります。
ABC191-B
問題「長さNの整数列Aと整数X、AからXを除いたものを出力」
「N X
A1 A2 A3…AN」
これは問題文だけでも理解できるかと思いますが、一応例1を見ておきます。
「5 5
3 5 6 5 4」
[3,5,6,5,4]という5つの要素から5を除外すると、[3,6,4]です。ただアルゴリズムの方針は違うものをまとめて返す、そのためにfilterを使います。
'use strict'
function main(input) {
input = input.trim().split("\n");
let items = input.map((item)=>item.split(" ").map(Number));
let N = items[0][0];
let X = items[0][1];
let A = items[1];
const result = A.filter(n => n !== X);
console.log(result.join(" "));
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
Aは配列でそれをfilterにかけます。どのような処理をするかですが、それぞれ要素nを実行文に渡し、nがXと同じでない時、その同じでなかったものをresultに返します。今回は5と同じではない[3,6,4]がresultに返され、これを半角空白でまとめるjoin(“ ”)を出力。
ABC190-B
問題「N種類の魔法、i番目の呪文はXi秒かかり、威力はYiです。魔物にはS秒以上かかったり威力D以下の呪文はダメージを与えられない。ダメージを与えることができるか?YesかNoで」
「N S D
X1 Y1
.
.
XN YN」
という複雑な入力ですが、これも例を見れば仕組みはシンプルです。例1は
「4 9 9
5 5
15 5
5 15
15 15」
2,4番目は15なので9秒以上かかるのでなし、1,2番目は5で9以下なのでなし、つまり3番目の呪文はダメージを与えられるのでYes
'use strict'
function main(input) {
input = input.trim().split("\n");
let items = input.map((item)=>item.split(" ").map(Number));
let N = items[0][0];
let S = items[0][1];
let D = items[0][2];
let ans = "No";
for(let i = 1; i <= N; i++) {
let X = items[i][0];
let Y = items[i][1];
if(X < S && Y > D) {
ans = "Yes";
break;
}
}
console.log(ans);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
特に説明することもないコードですが…ansをNoで用意しておいて、for文はitems[0]の4 9 9は要らないので、let i = 1からNまでループします。if文はS秒以下でかつ威力Dのものが1つでもあればその時点でansはYesにして終了break。問題文通りに書けば意外といけた系の問題でした。
ABC189-B
問題「N杯のお酒を飲んだ。i番目のお酒は量がVi ml、アルコール度数Pi %です。アルコール摂取量がX mlを超えると酔っぱらう。酔っぱらったのは何杯目を飲んだ時か?酔ってないなら-1を出力」
「N X
V1 P1
VN PN」
という入力で例1は
「2 15
200 5
350 3」
摂取量とパーセントの関係に注意して、計算して変換する必要があります。1杯目は200×(5÷100)で10mlのアルコールが含まれています。2杯目は350×(3÷100)で10.5mlのアルコールが含まれています。2杯目を飲んでいる時に15を超えるので出力するのは「2」
'use strict'
function main(input) {
input = input.trim().split("\n");
let items = input.map((item)=>item.split(" ").map(Number));
let N = items[0][0];
let X = items[0][1];
let alc = 0;
let ans = -1;
for(let i = 1; i <= N; i++) {
let V = items[i][0];
let P = items[i][1];
alc = alc + (V * P);
if(alc > X * 100) {
ans = i;
break;
}
}
console.log(ans);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
アルコール摂取量をalc = 0、ansを酔わないことを想定し-1にしておきます。 この問題も問題文を理解すればその通りにコードを記述すればよさそうな問題ですが、実はちょっと問題がありました… コードテストではalc = alc + (V * P /100)で出力出来ていたのですが、提出するとなぜかWA… これでは小数点以下が切り捨てられてしまうため、そのままalcを足し上げていくと、その分の誤差が生じるのでした。よってif文の中でXの方を100倍し、それを積み上げたalcが超えたらansをその時のiにします。
ABC188-B
問題「2つのN次元ベクトルA=(A1,A2,A3,…AN)とA=(B1,B2,B3,…BN)があります。AとBの内積が0かどうかを判定」
何のこと?と思いますが、問題文にも書かれているようにA1B1+A2B2+A3B3…ANBN=0であれば”Yes”にします。入力は横に広がっていく形です。
「N
A1 A2 A3 … AN
B1 B2 B3 …BN」
例1は
「2
-3 6
4 2」
なので内積は(-3)×4 + 6×2 = 0になるので”Yes”
'use strict'
function main(input) {
input = input.trim().split("\n");
let items = input.map((item)=>item.split(" ").map(Number));
let N = items[0];
let total = 0;
let ans = "No";
for(let i = 0; i < N; i++) {
let A = items[1][i];
let B = items[2][i];
total += (A * B);
}
if(total === 0) {
ans = "Yes";
}
console.log(ans);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
入力のAは2行目なのでitems[1][i]で、Bは3行目なのでitems[2][i]になりiが増えていくごとに右にズレていきます。掛け合わせたものをtotalに足し上げて、if文でtotalが0だったらansを”Yes”にします。
コメント