問題ページ
問題文
人気な表計算システム(例えばExcelとか)では、列の表現方法として、以下に述べる方法が使われています。
- 1列目はAという番号を持っています。2列目はB,3列目はC,...,26列目はZという番号を持っています。
- それ以降は二つの文字を使います。27列目はAA,28列目はAB,...,52列目はAZです。
- ZZの後には同じように3文字を使って表します。
行は1から始まる整数によって番号付けされています。セルの名前はセルの列と行の連なりです。例えば、BC23は、55列目23行目のセルの名前です。
時々、もうひとつ別の表現方法が用いられることがあります。その表現方法は、RXCY(XとYは整数で、それぞれ列と行番号を意味する) です。たとえば、R23C55は先ほどの例のセルを指します。
あなたの仕事は与えられた一連のセルの座標を読み込み、それぞれの座標について別の表現方法に従って出力することです。
制約
- 1≦n≦10^5(nは整数)
- 列番号も行番号も10^6を超えないデータしか与えられない。
- 正しい番号が与えられることが保障されている。
解法
反転↓
頑張って文字列の基数変換する。微妙に値弄ってやる(1足しながら10進数にしたり1引きながら戻したり)と辻褄があってうれしい。ソースは冗長。
#include <iostream> #include <queue> #include <algorithm> #include <cstdio> #include <cstdlib> #include <sstream> using namespace std; #define INF (1<<29) typedef unsigned int uint; int isAnother(string s){ if(s[0] != 'R') return false; if( !('0' <= s[1] && s[1] <= '9') )return false; if(s.find("C") == -1) return false; return true; } string toString(int n){ n--; if(n == -1) return ""; return toString(n/26) + string( 1 , 'A' + n % 26); } int toInt(string s){ int ans = 0; for(int i = 0 ; i < s.size() ; i++) ans = ans * 26 + (s[i] - 'A') + 1; return ans; } int main(){ int n; cin >> n; while(n--){ string s; cin >> s; if(isAnother(s)){ for(int i = 0 ; i < s.size() ; i++) if( !('0' <= s[i] && s[i] <= '9') ) s[i] = ' '; stringstream ss(s); int a,b; ss >> a >> b; cout << toString(b) << a << endl; }else{ int p = s.find_first_of("0123456789"); int a = toInt(s.substr(0,p)); int b = atoi(s.substr(p).c_str()); cout << "R" << b << "C" << a << endl; } } }