C - abc285_brutmhyhiizp Editorial by physics0523
まず、 \(k\) 文字の ID は \(26^k\) 通りあることがわかります。
また、 \(k\) 文字以下の ID は全部で \(26^1+26^2+\dots+26^k\) 通りであることもわかります。
では、 \(l\) 文字の ID である \(S\) が何問目かを実際に求めていきましょう。
実は、以下のように計算することが可能です。
最初、答えを \(26^1 + 26^2 + \dots + 26^{l-1}\) で初期化する。
- \(i = 1,2,\dots,l\) について以下を繰り返す。
- \(S\) の \(i\) 文字目がアルファベット大文字辞書順で \(x\) 番目であった場合、答えに \((x-1) \times 26^{l-i}\) を加算する。
最後に答えに \(1\) を加算して出力する。 (この加算によって \(0\) 始まりの番号付け(0-indexed) から \(1\) 始まりの番号付け(1-indexed) に切り替えられます。)
この解法にはいくつかの解釈があります。
例えば ID が QWERTY
であるとき、答えを以下のように数えていくことができます。
順を追って数え上げる
- \(5\) 文字以下の ID は全部で \(26^1 + 26^2 + \dots + 26^5\) 通り
- \(6\) 文字で
A
から始まる IDA?????
は \(26^5\) 通り - \(6\) 文字で
B
から始まる IDB?????
は \(26^5\) 通り - \(\vdots\)
- \(6\) 文字で
P
から始まる IDP?????
は \(26^5\) 通り - \(6\) 文字で
QA
から始まる IDQA????
は \(26^4\) 通り - \(6\) 文字で
QB
から始まる IDQB????
は \(26^4\) 通り - \(\vdots\)
- \(6\) 文字で
QWA
から始まる IDQWA???
は \(26^3\) 通り - \(\vdots\)
- \(6\) 文字で
QWEA
から始まる IDQWEA??
は \(26^2\) 通り - \(\vdots\)
- \(6\) 文字で
QWERA
から始まる IDQWERA?
は \(26^1\) 通り - \(\vdots\)
- \(6\) 文字で
QWERTA
から始まる IDQWERTA
は \(26^0\) 通り - \(\vdots\)
\(26\) 進数として解釈する
- \(5\) 文字以下の ID は全部で \(26^1 + 26^2 + \dots + 26^5\) 通り
というところは同じですが、 QWERTY
を \(26\) 進数として解釈します。
AAAAAA
が \(0\) 番目、 AAAAAB
が \(1\) 番目、 \(\dots\) 、 AAAAAZ
が \(25\) 番目、 AAAABA
が \(26\) 番目、 \(\dots\) というように番号を付けた際、各英大文字を \(0,1,\dots,25\) と対応付けることによって、文字列を \(26\) 進数と同様に取り扱うことができます。なので、入力を \(26\) 進数と解釈し \(10\) 進数に直して出力するようなことを行えばよいです。
実装例 (C++) :
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
cin >> s;
int l=s.size();
long long res=0,add=26;
for(int i=1;i<=l-1;i++){res+=add;add*=26;}
long long num=0;
for(int i=0;i<l;i++){
num*=26;
num+=(s[i]-'A');
}
cout << res+num+1 << "\n";
return 0;
}
posted:
last update: