ADDED SRM/509-U/1A.cpp Index: SRM/509-U/1A.cpp ================================================================== --- SRM/509-U/1A.cpp +++ SRM/509-U/1A.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef complex CMP; + +class LuckyRemainder { public: + int getLuckyRemainder(string X) + { + int sum = 0; + int N = X.size()-1; + for(int i=0; i +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const int& Expected, const int& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, LuckyRemainder().getLuckyRemainder(X));} +int main(){ + +CASE(0) + string X = "123"; + int _ = 6; +END +CASE(1) + string X = "24816"; + int _ = 3; +END +CASE(2) + string X = "8"; + int _ = 8; +END +CASE(3) + string X = "11235813213455"; + int _ = 7; +END +CASE(4) + string X = "1"; + int _ = 1; +END +CASE(4) + string X = "4"; + int _ = 4; +END +CASE(4) + string X = "9"; + int _ = 0; +END +/* +CASE(5) + string X = ; + int _ = ; +END + */ +} +// END CUT HERE ADDED SRM/509-U/1B.cpp Index: SRM/509-U/1B.cpp ================================================================== --- SRM/509-U/1B.cpp +++ SRM/509-U/1B.cpp @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef complex CMP; + +class PalindromizationDiv1 { public: + static const int INF = 0x3fffffff; + static const int NOLETTER = 26; + + int getMinimumCost(string word, vector operations) + { + // Cost for changing a character to another + int cost[27][27]; + for(int a=0; a<27; ++a) + for(int b=0; b<27; ++b) + cost[a][b] = (a==b ? 0 : INF); + + for(size_t i=0; i> cmd; + + char a, b; int c; + if( cmd == "add" ) { cin >> a >> c; cost[NOLETTER][ a - 'a'] = c; } + if( cmd == "erase" ) { cin >> a >> c; cost[ a - 'a'][NOLETTER] = c; } + if( cmd == "change" ){ cin >> a >> b >> c; cost[ a - 'a'][ b - 'a'] = c; } + } + + // Warshall-Floyd + for(int k=0; k<27; ++k) + for(int i=0; i<27; ++i) + for(int j=0; j<27; ++j) + cost[i][j] = min(cost[i][j], cost[i][k]+cost[k][j]); + + // Cost for matching two letters + int match_cost[27][27]; + for(int i=0; i<27; ++i) + for(int j=0; j<27; ++j) + { + match_cost[i][j] = INF; + for(int k=0; k<27; ++k) + match_cost[i][j] = min(match_cost[i][j], cost[i][k]+cost[j][k]); + } + + // Solve + memo.clear(); + int r = rec(match_cost, word, 0, word.size()-1); + return (r>=INF ? -1 : r); + } + + map,int> memo; + int rec(const int mc[27][27], const string& w, int s, int e) + { + // Base case + if( s >= e ) + return 0; + + // Memoizaion + const pair key(s, e); + if( memo.count(key) ) + return memo[key]; + + // take best + int result = INF; + result = min(result, rec(mc, w, s+1, e-1)+mc[w[s]-'a'][w[e]-'a']); + result = min(result, rec(mc, w, s, e-1)+mc[NOLETTER][w[e]-'a']); + result = min(result, rec(mc, w, s+1, e )+mc[w[s]-'a'][NOLETTER]); + return memo[key] = result; + } +}; + +// BEGIN CUT HERE +#include +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const int& Expected, const int& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, PalindromizationDiv1().getMinimumCost(word, operations));} +int main(){ + +CASE(0) + string word = "racecar"; + vector operations; + int _ = 0; +END +CASE(1) + string word = "topcoder"; + string operations_[] = {"erase t 1", "erase o 1", "erase p 1", "erase c 1", "erase d 1", "erase e 1", "erase r 1"}; + vector operations(operations_, operations_+sizeof(operations_)/sizeof(*operations_)); + int _ = 5; +END +CASE(2) + string word = "topcoder"; + string operations_[] = {"erase t 10", "erase o 1", "erase p 1", "erase c 1", "erase d 1", "erase e 1", "erase r 1"}; + vector operations(operations_, operations_+sizeof(operations_)/sizeof(*operations_)); + int _ = 7; +END +CASE(3) + string word = "caaaaaab"; + string operations_[] = {"change b a 100000", "change c a 100000", "change c d 50000", "change b e 50000", "erase d 50000", "erase e 49999"}; + vector operations(operations_, operations_+sizeof(operations_)/sizeof(*operations_)); + int _ = 199999; +END +CASE(4) + string word = "moon"; + string operations_[] = {"erase o 5", "add u 7", "change d p 3", "change m s 12", "change n d 6", "change s l 1"}; + vector operations(operations_, operations_+sizeof(operations_)/sizeof(*operations_)); + int _ = -1; +END +CASE(5) + string word = "a"; + vector operations; + int _ = 0; +END +CASE(6) // killer! + string word = "az"; + string operations_[] = {"add u 1", "change u b 100", "change a b 2"}; + vector operations(operations_, operations_+sizeof(operations_)/sizeof(*operations_)); + int _ = 103; +END +CASE(7) // killer! + string word = "az"; + string operations_[] = {"add b 1", "change a b 1"}; + vector operations(operations_, operations_+sizeof(operations_)/sizeof(*operations_)); + int _ = 2; +END +} +// END CUT HERE