SRM663 ABBA

ある文字列Iに,2つの操作が出来る.
- 文字列の最後に"A"を足す
- 文字列を反転して,最後に"B"を足す

文字列Iが文字列Tになるかを判定せよ

考察

愚直にIに操作していくと,2T.size()-I.size()で無理.しかしTから減らしていくには,一意しかない.末尾が"A"ならば,一つ前の状態をpreTとすると,T = preT+“A"となる.まと同様に,末尾が"B"ならば,T = reverse(preT) + "B"である.これを繰り返し,Iと同じsizeになった時に,同じかどうかで判定できる.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#line 5 "ABBA.cpp"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <queue>
#include <set>
#include <map>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;
typedef long long ll;

class ABBA {
  public:
  string canObtain(string I, string T) {

        while(T != I && T.size() > I.size()) {
            if(T[T.size()-1] == 'A') {
                T = T.substr(0,T.size()-1);
            }else {
                T = T.substr(0,T.size()-1);
                reverse(T.begin(),T.end());
            }
        }

        if(T == I) return "Possible";
        return "Impossible";
  }
};

コードを短く,シンプルにかける.本番中は誤読をしていて死んでいた.このある状態を目的の状態にする問題で,逆からやると上手くいく系はすぐ解けるようになりたい.

Jul 24th, 2015