Sony GO FOR IT 3)暗号検索の高速化

i)

# coding: utf-8
# ライセンス:このプログラムは、好きに使ってください。

import sys

# 問題のランダム文字列を生成
def makerandom():
    R = []
    r = 16
    for i in xrange(3000000):
        r = (r*1103515245+12345)&0xFFFFFFFF
        R += [chr(0x61+(26*(r/0x10000))/0x10000)]
    open("random.txt","w").write("".join(R))

#makerandom()
#exit()

key = sys.argv[1]
keyr = key[::-1]
R = raw_input()
for s in xrange(1,len(R)):
    for i in xrange(len(R)):
        t = R[i:i+len(key)*s:s]
        if t==key or t==keyr:
            print "%s,%s"%(s,i+1) 

ii)

//  ライセンス:このプログラムは、好きに使ってください。

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <ctime>
#include <cstdio>
using namespace std;

int main( int argc, char **argv )
{
    //  ランダム文字列
    string R;
    getline(cin,R);
    int N = (int)R.length();
    //  キーワード
    string key = argv[1];
    int n = (int)key.length();
    
    //  キーワードが回文かどうか
    string keyr = key;
    reverse(keyr.begin(),keyr.end());
    bool pal = key==keyr;
    
    //  キーワードの2文字目の出現位置
    vector<int> S;
    for ( int i=0; i<N; i++ )
        if ( R[i]==key[1] )
            S.push_back(i);
    
    //  キーワードが出現するスキップ数と位置
    vector<pair<int,int> > K;
    
    for ( int i=0; i<N; i++ )
    if ( R[i]==key[0] )
    {
        //  進行状況を表示
        if ( i%100==0 )
            printf( "%d/%d (%d%%) found %d\r", i, N, i*100/N, (int)K.size() );
        
        for ( int j=0; j<(int)S.size(); j++ )
        {
            //  スキップ数
            int s = S[j]-i;
            
            //  回文の場合は負の方向は考えない
            if ( pal && s<0 )
                continue;
            
            //  3文字目以降をチェック
            bool f = true;
            for ( int k=2, a=i+s*2; k<n&&f; k++, a+=s )
                if ( a<0 || N<=a || key[k]!=R[a] )
                    f = false;
            
            //  キーワードが出現している
            if ( f )
                if ( s>=0 )
                    K.push_back( make_pair(s,i+1) );
                else
                    K.push_back( make_pair(-s,i+s*(n-1)+1) );
        }
    }
    
    //  ソートして出力
    sort( K.begin(), K.end() );
    
    printf( "\n" );
    for ( int i=0; i<(int)K.size(); i++ )
        printf( "%d,%d\n", K[i].first, K[i].second );
    
    printf( "%.2f sec.\n", (float)clock()/CLOCKS_PER_SEC );
    
    return 0;
}