備忘録

まとめておきたいことのメモ 主にプロコンのこと

AOJ-ICPC 2006

今日といたのはこの問題。

Keitai Message | Aizu Online Judge

ガラケーのように、数字のかかれたボタンを何回か押すことによって打つ文字を決定させることができる場合に、次の数列がどのような文字列となるか考えなさい、という問題です。
1~9までにはそれぞれ3~5つの文字が振り当てられており、0のボタンを押すことによって入力を確定させることができるようです。たとえば2のボタンには「a, b, c」の3つの文字が当てられていて、「20」と押すと「a」、「222220」とおすとbが入力できます。

答えがこちら。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <ctype.h>
#include <string> 
#include <sstream>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#include <set>
  
using namespace std;
 
int main()
{
    string phone[10] = {".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    int n;
    string input;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> input;
        int l = input.length();
        int j = 0;
        while(1){
            int c1 = 0;
            while(c1 == 0 && j < l){
                c1 = input[j] - '0';
                j++;
            }
            if(j == l) break;
            int l2 = phone[c1 - 1].length();
            int k = 0;
            while(c1 == input[j] - '0'){
                j++;
                k++;
            }
            cout << phone[c1 - 1][k % l2];
        }
        cout << endl;
    }
    return 0;
}

入力された数列をとりあえずinputに保存します。lはinputの長さを表します。
j番目(jの初期値は0)の数字を見て、それが0である場合はつぎの文字へ移り、0ではない数字を探します。これをc1としています。
見つかってからはkを用いてその数字が何回連続で入力されたかを数えます。
kをl2(c1-1番目のボタンに割り当てられた文字の個数)で割ったあまりを用いることで正しく文字が表示できます。
これを繰り返し、jがlに一致したら終了です。

わりとすっきりかけたんじゃないかな。c1から1引くのを忘れたりjはlより小さいとダメとかいろいろと条件を忘れていたけど。
あと謎にfloating point exceptionというエラーが出たりしました(どういうときにでたのかはメモするの忘れてた)。float型使ってないのにね。よくわからん。