マップの判定・縦 (paizaランク C 相当)
JavaScriptで解いてみました。
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map(Number);
//盤面
const board = lines.slice(1).map(line => line.split(""));
//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
//x座標、列について
for (let j = 0; j < W; j++) {
//上端のマスの場合は「下のマスが '#'」であれば
if (i === 0 && board[1][j] === "#") {
console.log(`${i} ${j}`);
//下端のマスの場合は「上のマスが '#'」であれば
} else if (i === H - 1 && board[H - 2][j] === "#") {
console.log(`${i} ${j}`);
//上下のマスがどちらも '#' であれば
} else if (i !== 0 &&
i !== H - 1 &&
board[i - 1][j] === "#" &&
board[i + 1][j] === "#") {
console.log(`${i} ${j}`);
}
} //for j
} //for i
解答例(列判定)
上下ではなく、列で調べました。
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map((num) => Number(num));
//盤面
const board = [];
for (let i = 1; i <= H; i++) {
board.push(lines[i]);
}
//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
//x座標、列について
for (let j = 0; j < W; j++) {
//列が#か判定
let colum = false;
//上端のマスの場合は「下のマスが '#'」であれば
if (i === 0 && board[1][j] === "#") {
colum = true;
}
//下端のマスの場合は「上のマスが '#'」であれば
if (i === H - 1 && board[H - 2][j] === "#") {
colum = true;
}
//上下のマスがどちらも '#' であれば
if (i !== 0 &&
i !== H - 1 &&
board[i - 1][j] === "#" &&
board[i + 1][j] === "#") {
colum = true;
}
//左右上下全て#ならば
if (row && colum) {
console.log(`${i} ${j}`);
}
} //for j
} //for i
解答例(python3の場合の模範解答参考)
列で、上側・上端と下側・下端をまとめました。
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map((num) => Number(num));
//盤面
const board = lines.slice(1).map(line => line.split(""));
//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
//x座標、列について
for (let j = 0; j < W; j++) {
//列について#か判定
let row = false;
//列について
//上側、上端または"#"ならば
if (i === 0 || board[i - 1][j] === "#") {
//下側、下端または"#"ならば
if (i === H - 1 || board[i + 1][j] === "#") {
colum = true;
}
}
//上下全て#ならば
if (colum) {
console.log(i,j);
}
} //for j
} //for i
解答例(C++の場合の模範解答参考)
上下を調べるときに、移動の変化量である [-1,1] を配列 move で持つと、for文+if文1つにできます。
上下の全てで条件を満たすかどうかを判定するために 変数 ok を用います。
盤面内 かつ #でなかったときに、falseにします。
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map((num) => Number(num));
//盤面
const S = Array(H);
for (let i = 0; i < H; i++) {
S[i] = lines[i + 1];
}
//移動の変化量move
let move = [-1, 1];
//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
//x座標、列について
for (let j = 0; j < W; j++) {
//上下の全てで条件を満たすかどうかを判定
let ok = true;
//kはmoveのインデックス,move[k] = -1 または 1
for (let k = 0; k < 2; k++){
//jは列方向について、move[k] = -1上 または 1下 移動した時
//盤面内 かつ #でないなら ok=false
if(0 <= j+move[k] && j+move[k] < W &&
S[i][j+move[k]] !== '#'){
ok = false;
break;
}
}
//上下全て#ならば
if (ok) {
console.log(i + " " + j);
}
} //for j
} //for i
解答例(Rubyの場合の模範解答参考)
forEachを使いました。
上下のマスの文字が # のとき flag_clm を true にします。
端の時は問題に従ってtrueになるようにしています。
flag_clm で上下の全てのマスの文字 # であるかを判定できます。
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 h , 盤面の列数を表す整数 w
const [h, w] = lines[0].split(" ").map((num) => Number(num));
//盤面
const board = lines.slice(1).map(line => line.split(""));
//盤面全てのマスについて調べる
//y座標、行rowについて
board.forEach((row, y) => {
//x座標、列について
row.forEach((_, x) => { //第一引数は使わないので_にしています。
let flag_row = false;
let flag_clm = false;
//上下のマスの文字が # のとき flag_clm を true にします。
////端の時は問題に従ってtrueになるようにしています。
if (y === 0 || board[y - 1][x] === '#') {
if (y === h - 1 || board[y + 1][x] === '#') {
flag_clm = true;
}
}
/*flag_clm で上下左の全てのマスの文字が # であるかを判定できます。*/
if (flag_row && flag_clm) {
console.log(y + ' ' + x);
}
}); //forEach _ x
}); //forEach row y