備考
8/4に解いていたが、就活が落ち着いたことで体調を崩したりオリンピックの観戦をしたりで放っておいてしまった。
また、D問題までを解く予定であったが、D問題の極限の計算が合わなかったので、一旦はD問題以降は放っておくことにする。
A問題
考察
問題文の通りに条件分岐を実装する。
文法等
Progateを使ったのみで把握していないことが多かった。
実行方法
AtCoderのJavaScriptの実行環境はNode.jsである。
そのため、用意したJSファイルはnode ファイル名で実行することができる。
モジュールのインストール
Node.jsにおけるパッケージ管理ツールがnpmである。
また、npmはコマンドによりインストール等を行うことができる。
例えば、インストール用のコマンドはnpm install モジュール名となる(グローバルにインストールしたい場合は-g)。
ただし、AtCoderで使う場合は、標準であるモジュールしか用いることができなそうなので注意が必要(要確認)。
モジュールのインポート
JavaScriptではモジュールのインポートのためにimport文を用いるが、Node.jsの場合はrequire文が使うのが一般的なようである(要確認)。import文もNode.jsでは用いることができるようであるが、少なくともAtCoderではrequire文のみを用いるようにする(参考)。
入出力
readline-syncモジュールを利用することができなかったので、AtCoder公式のコードを参考にfsモジュールを利用した。
入力についてはこちらの記事にてテンプレートとしてまとめている。
コード
function Main(input) {
// 1行目がinput[0], 2行目がinput[1], …に入る
input = input.split("\n");
let a,b;[a,b]=input[0].split(" ").map((x)=>{return parseInt(x,10)});
if(a+b>=15 && b>=8){
console.log(1);
}else if(a+b>=10 && b>=3){
console.log(2);
}else if(a+b>=3){
console.log(3);
}else{
console.log(4);
}
}
// 標準入出力から一度に読み込み、Mainを呼び出す
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
B問題
考察
Nが最大で1000なので、二重ループが可能。以下では、従業員$i,j$について考える。
従業員$i,j$がそれぞれ仕事$A,B$もしくは$B,A$を行うとして任意の場合を考える。
→$max(A_i,B_j)$と$Math.max(B_i,A_j)$
また、一人の従業員がどちらの仕事も行う場合についても任意の場合も考える。
→$A_i+B_i$と$A_j+B_j$
文法
Mathモジュール
maxやminを含む、主要な数学系の関数や定数はこちらのモジュールにて定義されている(参考)。
整数
JSの整数(Number型)は32bit整数らしいので、それを超える場合はBigintを使う必要がある。
ただし、Bigintの場合は前述のMathモジュールの関数や定数を使うことができないので、注意が必要。
分割代入
配列やオブジェクトの分割代入が可能。Pythonのa,b=c,dのような機能を果たす。
また、スプレット構文を使うことで、分割代入はさらに便利になる(参考)。
コード
class Pair{
constructor(a,b){
this.a=a;
this.b=b;
}
sum(){
return this.a+this.b;
}
}
function Main(input) {
// 1行目がinput[0], 2行目がinput[1], …に入る
input = input.split("\n");
let n=input[0];
let x=[];
for(let i=1;i<=n;i++){
let a,b;
[a,b]=input[i].split(" ").map((i)=>{return parseInt(i,10)});
x.push(new Pair(a,b));
}
let ans=1<<30;
for(let i=0;i<n;i++){
for(let j=i+1;j<n;j++){
ans=Math.min(ans,Math.max(x[i].a,x[j].b),Math.max(x[i].b,x[j].a),x[i].sum(),x[j].sum());
}
}
console.log(ans);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
C問題
考察
下記のように式変形をすることで解くことができる。
\begin{align}
&\sum_{i=2}^{N}\sum_{j=1}^{i-1}(A_i-A_j)^2 \\
=&(n-1)\sum_{i=1}^{N}(A_i)^2-2\sum_{i=2}^{N}\sum_{j=1}^{i-1}(A_i \times A_j) \\
=&n\sum_{i=1}^{N}(A_i)^2-(\sum_{i=1}^{N}A_i)^2 \\
\end{align}
よって、ここで得られた式は$O(N)$で解を求めることができる。
文法等
mapメソッド
Pythonのmap関数ではmapオブジェクトを返すが、JSのmapメソッドは配列のメソッドなので配列を返す。
また、mapメソッドの引数に指定した関数を要素ごとに適用した配列を返り値として返す。
さらに、指定する関数にアロー関数を用いることで、簡単になる。
reduceメソッド
配列の各要素を前から順に演算を行なって演算結果を保存し、最終的な演算結果を返すメソッド。
また、演算として+演算子を用いれば、配列の総和を返すことができる。
詳しくはこちらを見た方が良いと思われる。
コード
function Main(input) {
// 1行目がinput[0], 2行目がinput[1], …に入る
input = input.split("\n");
let n=parseInt(input[0],10);
let a=input[1].split(" ").map(function(i){return parseInt(i,10)});
// pythonのreduceと同じ
let ans=(n)*a.map((x)=>x*x).reduce((i,j)=>i+j);
ans-=(a.reduce((i,j)=>i+j))**2;
console.log(ans);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
↧