感想
リアタイで参加したが、実装ミスなどにより最悪な結果となった。
D問題までは難しくなかったが、E問題が大きな壁になった。
E問題のように、操作をコストと捉えてダイクストラや01BFSに落とすのは以前に見たことがあったが、実戦から離れすぎて忘れてしまった。
再び精進する気があまりないので、Kaggleなどの別の競技をやってみるのが良いのかもしれない。
A問題
考察
$A \oplus C=B \leftrightarrow C=A \oplus B$なので、xorを計算するのみ。
文法
入力の部分が面倒なので、簡素化した方が良いかもしれない。
それ以外は特に感じたことはなかった。
コード
// inputに入力データ全体が入る
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)});
console.log(a^b)
}
//標準入出力から一度に読み込み、Mainを呼び出す
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
簡素ver
function toInt(x){
return parseInt(x,10);
}
// inputに入力データ全体が入る
function Main(input) {
// 1行目がinput[0], 2行目がinput[1], …に入る
input = input.split("\n");
let a,b;[a,b]=input[0].split(" ").map(toInt);
console.log(a^b)
}
//標準入出力から一度に読み込み、Mainを呼び出す
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
B問題
考察
スコアの降順に並べて2番目の数の番号を出力すれば良い。
出力するのは番号なので、スコアと番号を組にして持っておく。
文法
クラス
組にして持つために今回はクラスを使った。クラスについてはMDNのドキュメントに詳しいので、参考にされたい。
今回はクラス宣言を用いてクラスを定義した。Pythonでいうメンバ変数をプロパティと呼び、クラス内ではthis.プロパティ名によりアクセス/定義できる。クラス外ではインスタンス名.プロパティ名でアクセスできる。(通常の定義の場合はPrivateになる)
ソート
ソートがかなり癖がある。詳しくはMDNのドキュメントを参考にされたい。
まず、デフォルトの比較関数が、各要素を文字列に変換した際のUnicodeでのポイント順という仕様になっている。また、比較関数を自分で指定する時をここでは考える。
比較関数をcompareFunction(a,b)としたとき
compareFunction(a,b)が0未満の時
aをbより小さいインデックスにソートする
compareFunction(a,b)が0の時
aとbの位置を変えない(環境によっては保証されない)
compareFunction(a,b)が0より大きい時
aをbより大きいインデックスにソートする
コード
class player{
constructor(ind,ban){
this.ind=ind;
this.ban=ban;
}
}
// inputに入力データ全体が入る
function Main(input) {
// 1行目がinput[0], 2行目がinput[1], …に入る
let n,a,b;
[n,b]=input.split("\n");
n=parseInt(n,10);
a=[];
b=b.split(" ");
for(let i=0;i<n;i++){
a.push(new player(i,parseInt(b[i],10)));
}
a.sort((i,j)=>{return j.ban-i.ban;});
console.log(a[1].ind+1);
}
//標準入出力から一度に読み込み、Mainを呼び出す
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
C問題
考察
少なくとも一つのカードを含む行および列が残るので、座標圧縮を行えば良い。
出てくる行について重複がないように昇順に並べ、出てくる列について重複がないように昇順に並べることで座標圧縮を行うことができる。
最終的に求めるのは、それぞれのカードがどの座標へと移るかなので、出力の前にnowr[元の行]=移る先の行とnowc[元の列]=移る先の列を用意した。
文法
Set
重複を除くためにSetを利用した。new演算子によりインスタンスを生成でき、追加する際はaddメソッドを用いる。詳しくはMDNのドキュメントを参考にする。
オブジェクト(連想配列)
オブジェクトに対してドット表記か角括弧表記のいずれかでアクセスすることができる。
ドット表記の場合はプロパティであることを意識してアクセスする。また、プロパティは文字列と結びついているので、角括弧表記を用いて連想配列としてアクセすることができる。この時、プロパティ名は文字列に変換できるものであれば使用することができる。今回の場合は整数を用いている。
ただ、連想配列としてのみの利用の場合はMapオブジェクトを用いた方が良いと思われる(参考)。
コード
function compareNumbers(a,b){
return a - b;
}
// inputに入力データ全体が入る
function Main(input) {
// 1行目がinput[0], 2行目がinput[1], …に入る
input = input.split("\n");
let h,w,n;
[h,w,n]=input[0].split(" ").map((x)=>parseInt(x));
// r:行、c:列、候補
let r=new Set();
let c=new Set();
let card=[];
for(let i=1;i<=n;i++){
card.push(input[i].split(" ").map((x)=>parseInt(x)));
r.add(card[i-1][0]);
c.add(card[i-1][1]);
}
let nowr,nowc;
[nowr,nowc]=[{},{}];
r=Array.from(r);
r.sort(compareNumbers);
c=Array.from(c);
c.sort(compareNumbers);
for(let i=0;i<r.length;i++){
nowr[r[i]]=i+1;
}
for(let i=0;i<c.length;i++){
nowc[c[i]]=i+1;
}
for(let i=0;i<n;i++){
console.log(nowr[card[i][0]],nowc[card[i][1]]);
}
}
//標準入出力から一度に読み込み、Mainを呼び出す
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
↧