1
0

More than 1 year has passed since last update.

paizaラーニング レベルアップ問題集 Aランクレベルアップメニュー JavaScript マップの判定・横

Last updated at Posted at 2022-09-20

マップの判定・横 (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((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++) {

        //左端のマスの場合は「右のマスが "#"」であれば
        if (j === 0 && board[i][1] === "#") {
            console.log(`${i} ${j}`);
        
        //右端のマスの場合は「左のマスが "#" 」であれば
        }  else if (j === W - 1 && board[i][W - 2] === "#") {
            console.log(`${i} ${j}`);
       
        //左右のマスが”#”であれば
        } else if (board[i][j - 1] === "#" &&
                   board[i][j + 1] === "#") {
            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 row = false;
        
         //左端のマスの場合は「右のマスが "#"」であれば
        if (j === 0 && board[i][1] === "#") {
            row  = true;
        }
        //右端のマスの場合は「左のマスが "#" 」であれば
        if (j === W - 1 && board[i][W - 2] === "#") {
            row  = true;
        }
       
        //左右のマスが”#”であれば
        if (board[i][j - 1] === "#" &&
                   board[i][j + 1] === "#") {
            row  = true;
        }
       
        //左右全て#ならば
        if (row) {
            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 (j === 0 || board[i][j - 1] === "#") {
            //右側、右端もしくは"#"ならば
            if (j === W - 1 || board[i][j + 1] === "#") {
                row  = true;
            }
        }
 
        //左右全て#ならば
        if (row) {
            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++){
            //iは行方向について、move[k] = -1左 または 1右 移動した時
            //盤面内 かつ #でないなら ok=false
            if(0 <= i+move[k] && i+move[k] < H &&
             S[i+move[k]][j] !== '#'){
                ok = false;
                break;
            }
        }
        
        //左右全て#ならば
        if (ok) {
            console.log(i + " " + j);
        }

    } //for j
} //for i

解答例(Rubyの場合の模範解答参考)

forEachを使いました。
左右のマスの文字が # のとき flag_row を true にします。
端の時は問題に従ってtrueになるようにしています。
flag_rowで左右の全てのマスの文字 # であるかを判定できます。

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;
        
        //左右のマスの文字が # のとき flag_row を true にします。
        //端の時は問題に従ってtrueになるようにしています。
        if (x === 0 || row[x - 1] === '#') {
          if (x === w - 1 || row[x + 1] === '#') {
            flag_row = true;
          }
        }
       
        /*flag_rowで左右の全てのマスの文字が # であるかを判定できます。*/
        if (flag_row) {
          console.log(y + ' ' + x);
        }    
    }); //forEach _ x
}); //forEach row y
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0