2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript タプルソート

Last updated at Posted at 2022-09-12

paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript タプルソート

タプルソート (paizaランク B 相当)

解いてみました。

解答コード例(JavaScript) C++ の場合(1)の模範解答参考

ソート前に、優先順位の高い順にしておきます。この問題では、
[ k 列目, 1 列目, 2 列目, ..., k - 1 列目, k + 1 列目, ..., m 列目 ]
の順にしてから、優先順位の低い末尾からソートを実行し、その後、元に戻します。

JavaScript
  const fs = require("fs");
  const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
  const lines = input.split("\n");
  //n 行 m 列 の表 a , k 列目が昇順
  const [n, m, _] = lines[0].split(" ").map(Number);
  let [_, _, k] = lines[0].split(" ").map(Number);
  k--;//表aのインデックスで扱うので-1する

  //入力cin
  const cin = lines.slice(1).map(line => line.split(" ").map(Number));
  //表 a 
  const a = Array(n).fill(0).map(v => v = Array(m));
  // k 番目の値を配列の先頭に入れる
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < m; j++) {
      if (j === k) {
        a[i][0] = cin[i][j];
      } else if (j < k) {
        a[i][j + 1] = cin[i][j];
      } else {
        a[i][j] = cin[i][j];
      }
    }
  }

  //優先順位の低い末尾の列からソート実行
  for (let i = m - 1; i >= 0; i--) {
    a.sort((a, b) => a[i] - b[i]);
  }

  
  //戻し先の配列を作る
  const sorted = Array(n).fill(0).map(row => row = []);
  //先頭に入れた k 番目の値を元の位置に戻す
  for (let i = 0; i < n; i++) {
    //kの前
    for (let j = 1; j < k + 1; j++) {
      sorted[i].push(a[i][j]);
    }
    //kを元に戻す
    sorted[i].push(a[i][0]);
    //kの後
    for (let j = k + 1; j < m; j++) {
      sorted[i].push(a[i][j]);
    }
  }
  
  //出力
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < m; j++) {
      if (j === 0) {
        process.stdout.write(String(sorted[i][j]));
      } else {
        process.stdout.write(" " + String(sorted[i][j]));
      }
    }
    process.stdout.write("\n");
  }

表aを作るところは、メソッドを使って以下のようにも書けます。

JavaScript
  //表 a 
  const a = [];
  // k 番目の値を配列の先頭に入れる
  for (let i = 0; i < n; i++) {
    const a_i = lines[i + 1].split(" ").map(Number);//表aのi行目
    const head = a_i.splice(k, 1);//k番目を抜く
    a_i.unshift(...head);//抜いたk番目を先頭につける
    a.push(a_i);//表aのi行目にpush
  }

最後の出力のところは、以下のように1行でも書けます。

JavaScript
  //出力
  console.log(a.map(row => row.join(" ")).join("\n"));

解答コード例(JavaScript) C++ の場合(2)の模範解答参考

sort関数の中で、優先順位にしたがって、ifで場合分けをしても解くことができます。
ifは先に来る方が優先されます。
k 番目の値が等しくない場合はすぐに比較が完了します。k 番目の要素が最優先だからです。
k 番目の値が等しい場合は k 番目以外の値を先頭から順に見ていきます。

JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//n 行 m 列 の表 a , k 列目が昇順
let [n, m, k] = lines[0].split(" ").map(Number);
k--;//表aのインデックスで扱うので-1する

//表 a
const a = lines.slice(1).map(line => line.split(" ").map(Number));
 
//ソート実行
a.sort((a_l, a_r) => {
  //ifは優先順位が高い方が先
  if (a_l[k] !== a_r[k]) { // k 番目の要素の値が異なるとき 
    return a_l[k] - a_r[k]; //k 列目を昇順に
  } else { //k 番目の要素の値が等しかったら、
    for (let i = 0; i < a_l.length; i++) { //i番目の要素の値を調べる
      if (i === k) { //k 番目の要素はスキップ
        continue;
      }
      if (a_l[i] !== a_r[i]) { // i番目の要素の値が異なるとき
        return a_l[i] - a_r[i]; // i 列目の値を昇順に
      }
    }
    // すべての要素の値が等しいとき
    return 0;
  }  
});

//出力
for (let i = 0; i < n; i++) {
    for (let j = 0; j < m; j++) {
      if (j === 0) {
        process.stdout.write(String(a[i][j]));
      } else {
        process.stdout.write(" " + String(a[i][j]));
      }
    }
    process.stdout.write("\n");
}

こちらも最後の出力のところは、以下のように1行でも書けます。

JavaScript
  //出力
  console.log(a.map(row => row.join(" ")).join("\n"));
2
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?