@tetrocky

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【AtCoder】ABC416 C - JavaScriptのN進数ロジックが正しいはずなのにWAになります

AtCoderの問題で、自分ではロジックが正しいと確信しているコードが、どうしてもWA(Wrong Answer)になってしまいます。

ローカルでのいくつかのテストケースは通過するのですが、提出するとWAとなります。
JavaScript特有の仕様を踏んでいるのか、あるいはロジックの根本的な見落としがあるのか分からず、皆様のお力をお借りしたく投稿します。


1. 問題のURL

ABC416 C - k-th string
https://atcoder.jp/contests/abc416/tasks/abc416_c

2. 提出してWAになったコード

(ローカルの input.txt とAtCoderの標準入力を自動で切り替えるテンプレートを使用しています)

'use strict';

const fs = require('fs');
const readline = require('readline');

const isAtCoder = process.platform === 'linux';

const inputStream = isAtCoder
    ? process.stdin
    : fs.createReadStream('./input.txt');

const rl = readline.createInterface({
    input: inputStream,
});

const input = [];
rl.on('line', (line) => {
    input.push(line);
});

rl.on('close', () => {
    const [n, k, x] = input[0].split(' ').map(Number);

    // 入力されたSnをソート
    const S = [];
    for(let i=1; i<n+1; i++){
        S.push(input[i]);
    }
    const sortedS = S.sort();

    // xを0-indexedにする
    let xLeft = x-1;
    const nStringX = []; // N進数に変換したときの各桁の数字を格納
    
    // xLeft を K桁のN進数に変換(上の桁から決定)し、nStringXに格納
    for(let j=k-1; j>=0; j--){
        const nPowJ = n**j;
        const index = Math.floor(xLeft / nPowJ);
        nStringX.push(index);
        xLeft = xLeft % nPowJ;
    }

    // nStringXの各要素をsortedSのindexに対応させて結果を出力する
    const resultS = [];
    for(const l of nStringX){
        resultS.push(sortedS[l]);
    }
    console.log(resultS.join(''));
});

3. 私の考えたロジック(アルゴリズム)

この問題は、N 個の文字列を「N 進数の K 桁の数字」として解釈する問題だと考えました。

  1. まず、入力された N 個の文字列 S を辞書順にソートします (sortedS)。
    これが N 進数における 0 から N-1 までの「数字」に相当すると考えました。
  2. 問題文は X 番目(1-indexed)を求めていますが、プログラムでは 0-indexed で扱うため、xLeft = x - 1 とします。
  3. この xLeft を、「K 桁の N 進数」に変換します。
    • コードの for ループでは、n**(k-1) の位(一番上の桁)から順番に、xLeftn**j で割った商を index (その桁の数字)としています。
    • xLeftn**j で割った余りを、次の桁の計算に回します。
  4. これにより、xLeftnStringX = [d_k-1, d_k-2, ..., d_0] という N 進数の各桁の数字(sortedS のインデックスに対応)に変換されます。
  5. 最後に、nStringX の各要素 l をインデックスとして sortedS[l] を取り出し、join('') で連結して答えとしています。

4. 困っている点・不可解な点

ロジックは正しいと信じているのですが、どうしてもWAになってしまいます。
このロジックにはどのような欠陥があるのでしょうか? あるいは、JavaScript特有の仕様で見落としている点があるのでしょうか?

どのような反例でこのコードがWAになるか、お心当たりのある方がいらっしゃいましたら、ご教示いただけますと幸いです。

よろしくお願いします。

0 likes

1Answer

とりあえず反例を挙げておきます。以下の入力例で、正しい出力はbabですが、ご提示のコードだとbbが出力されます。

2 2 1
ba
b
0Like

Your answer might help someone💌