#include typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() using namespace std; class GoodProblem2 { public: void solve(void) { int T; cin>>T; while (T--) { string S; cin>>S; const int inf = (1<<30); int N = S.length(); // S[i] からスタートしたとき problem,good にするために必要な置換数 vector probCost(N,inf); vector goodCost(N,inf); const string good = "good"; const string prob = "problem"; // O(N*10) for (int i = 0; i+6 < N; ++i) { probCost[i] = 0; REP(j,7) { if ( S[i+j] != prob[j] ) ++probCost[i]; } } for (int i = 0; i+3 < N; ++i) { goodCost[i] = 0; REP(j,4) { if ( S[i+j] != good[j] ) ++goodCost[i]; } } // S[i] 以降で problem を作るときの最小コストを計算 for (int i = N-8; i >= 0; --i) probCost[i] = min(probCost[i], probCost[i+1]); // 最初に見つかる good が problem の後ろにある場合の追加コスト // S[i] 以前に problem が出現している回数を累積しておけばよい vector addCost(N,0); for (int i = 6; i < N; ++i) { int j; addCost[i] = addCost[i-1];// 累積 for (j = 0; j < 7; ++j) { if ( S[(i-6)+j] != prob[j] ) break; } // match if ( j == 7 ) ++addCost[i]; } int ret = inf; for (int i = 0; i+6 < N; ++i) ret = min(ret, goodCost[i] + addCost[i] + probCost[i+4]); cout<solve(); delete obj; return 0; } #endif