TopCoder: SRM

Problem Statement

    

Given a base word, original, and a compound word, compound, decide if the compound word is valid. A compound word is valid if and only if it is comprised solely of a concatenation of prefixes and/or suffixes of original. That is, if the compound word can be partitioned into N parts, such that each part is equal to either a prefix or a suffix of original, then it is valid. If the word is invalid, return -1. Otherwise, return the minimum value of N for which this is possible.

Definition

    
Class: WordParts
Method: partCount
Parameters: string, string
Returns: int
Method signature: int partCount(string original, string compound)
(be sure your method is public)
    
 

Notes

- The entire base word original is considered a valid prefix/suffix of itself. See example 3.

Constraints

- original will contain between 1 and 50 characters, inclusive.
- original will consist only of uppercase letters (A-Z).
- compound will contain between 0 and 50 characters, inclusive.
- compound will consist only of uppercase letters (A-Z).

Examples

0)  
    
"ANTIDISESTABLISHMENTARIANISM"
"ANTIDISIANISMISM"
Returns: 3

"ANTIDISIANISMISM" can be split into "ANTIDIS", "IANISM", and "ISM", all of which are substrings from the beginning or end of the base word.

1)  
    
"ANTIDISESTABLISHMENTARIANISM"
"ESTABLISHMENT"
Returns: -1

While "ESTABLISHMENT" is contained in "ANTIDISESTABLISHMENTARIANISM", it neither starts at the beginning nor ends at the end of that string. Furthermore, "ESTABLISHMENT" cannot be broken into any number of parts which satisfy this rule.

2)  
    
"TOPCODERDOTCOM"
"TOMTMODERDOTCOM"
Returns: 5
The five strings are "TO", "M", "T", "M", and "ODERDOTCOM".
3)  
    
"HELLO"
"HELLOHEHELLOLOHELLO"
Returns: 5

Note that the entire original word is considered a valid prefix/suffix.

4)  
    
"DONTFORGETTHEEMPTYCASE"
""
Returns: 0
 
5)  
    
"BAAABA"
"BAAABAAA"
Returns: 2
 
6)  
    
"ABBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABB"
"BBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABAA"
Returns: 17

一开始用贪心算法,如果是前缀或者后缀长度加长看仍然是不是,这个算法可以达到局部最优,但是从第五个例子报错看出不是全局最优。于是想了个dfs的算法,第六个例子运行很慢,code block里虽然最终能运行出不过放IDE里果断TLE了,而且其他小例子也不知道为什么会报错,出现一个很奇怪的大数字,用VS跑了下也没这错误, anyway DFS算法肯定不对了。暂时想不出什么好的法子来解这个题目。网上看了一个人的代码,但是也不对,而且也看不懂&ret = m[pos]这行是什么意思。

贪心算法代码:

 1 // BEGIN CUT HERE

 2 

 3 // END CUT HERE

 4 #include <functional>

 5 #include <algorithm>

 6 #include <stdexcept>

 7 #include <iostream>

 8 #include <sstream>

 9 #include <fstream>

10 #include <iomanip>

11 #include <cstdlib>

12 #include <cstring>

13 #include <utility>

14 #include <cctype>

15 #include <vector>

16 #include <string>

17 #include <bitset>

18 #include <queue>

19 #include <stack>

20 #include <ctime>

21 #include <list>

22 #include <map>

23 #include <set>

24 #include <math.h>

25 

26 using namespace std;

27 

28 #define ll long long

29 #define MOD 1000000007

30 

31 class WordParts

32 {

33         public:

34         

35         bool check(string original, string s) {

36             int olen = original.size();

37             int slen = s.size();

38             if (slen > olen) return false;

39             if (s == original.substr(0, slen) || s == original.substr(olen-slen, slen)) return true;

40             return false;

41         }

42         int partCount(string original, string compound)

43         {

44             while (compound.size()) {

45                 bool flag = false;

46                 for (int i = compound.size(); i >= 1; i--) {

47                     if (check(original, compound.substr(0, i))) {

48                         flag = true;

49                         compound.erase(0, i);

50                         if (compound.size() == 0) return count+1;

51                         count++;

52                         break;

53                     }

54                 }

55                 if (flag) continue;

56                 else return -1;

57             }

58             return count;

59         }

60 

61 // BEGIN CUT HERE

62     public:

63     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); }

64     private:

65     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }

66     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }

67     void test_case_0() { string Arg0 = "ANTIDISESTABLISHMENTARIANISM"; string Arg1 = "ANTIDISIANISMISM"; int Arg2 = 3; verify_case(0, Arg2, partCount(Arg0, Arg1)); }

68     void test_case_1() { string Arg0 = "ANTIDISESTABLISHMENTARIANISM"; string Arg1 = "ESTABLISHMENT"; int Arg2 = -1; verify_case(1, Arg2, partCount(Arg0, Arg1)); }

69     void test_case_2() { string Arg0 = "TOPCODERDOTCOM"; string Arg1 = "TOMTMODERDOTCOM"; int Arg2 = 5; verify_case(2, Arg2, partCount(Arg0, Arg1)); }

70     void test_case_3() { string Arg0 = "HELLO"; string Arg1 = "HELLOHEHELLOLOHELLO"; int Arg2 = 5; verify_case(3, Arg2, partCount(Arg0, Arg1)); }

71     void test_case_4() { string Arg0 = "DONTFORGETTHEEMPTYCASE"; string Arg1 = ""; int Arg2 = 0; verify_case(4, Arg2, partCount(Arg0, Arg1)); }

72     void test_case_5() { string Arg0 = "BAAABA"; string Arg1 = "BAAABAAA"; int Arg2 = 2; verify_case(5, Arg2, partCount(Arg0, Arg1)); }

73     void test_case_6() { string Arg0 = "ABBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABB"; string Arg1 = "BBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABAA"; int Arg2 = 17; verify_case(6, Arg2, partCount(Arg0, Arg1)); }

74 

75 // END CUT HERE

76 

77 };

78 // BEGIN CUT HERE

79 int main()

80 {

81         WordParts ___test;

82         ___test.run_test(-1);

83         return 0;

84 }

85 // END CUT HERE

dfs代码:

 1 // BEGIN CUT HERE

 2 

 3 // END CUT HERE

 4 #include <functional>

 5 #include <algorithm>

 6 #include <stdexcept>

 7 #include <iostream>

 8 #include <sstream>

 9 #include <fstream>

10 #include <iomanip>

11 #include <cstdlib>

12 #include <cstring>

13 #include <utility>

14 #include <cctype>

15 #include <vector>

16 #include <string>

17 #include <bitset>

18 #include <queue>

19 #include <stack>

20 #include <ctime>

21 #include <list>

22 #include <map>

23 #include <set>

24 #include <math.h>

25 

26 using namespace std;

27 

28 #define ll long long

29 #define MOD 1000000007

30 

31 class WordParts

32 {

33         public:

34         bool check(string original, string s) {

35             int olen = original.size();

36             int slen = s.size();

37             if (slen > olen) return false;

38             if (s == original.substr(0, slen) || s == original.substr(olen-slen, slen)) return true;

39             return false;

40         }

41         void dfs(string original, string compound, int count, int &maxnum, int size) {

42             if (count+1 > maxnum) return;

43             if (check(original, compound)) {

44                 maxnum = min(maxnum, count+1);

45                 return;

46             }

47             string pre = compound;

48             for (int i = size-1; i >= 1; i--) {

49                 if (check(original, compound.substr(0, i))) {

50                     compound.erase(0, i);

51                     dfs(original, compound, count+1, maxnum, size-i);

52                     compound = pre;

53                 }

54             }

55         }

56         int partCount(string original, string compound)

57         {

58             int count = 0;

59             int maxnum = compound.size();

60             if (compound.size() == 0) return 0;

61             dfs(original, compound, count, maxnum, compound.size());

62             return maxnum == compound.size()? -1 : maxnum;

63         }

64 

65 // BEGIN CUT HERE

66     public:

67     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); }

68     private:

69     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }

70     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }

71     void test_case_0() { string Arg0 = "ANTIDISESTABLISHMENTARIANISM"; string Arg1 = "ANTIDISIANISMISM"; int Arg2 = 3; verify_case(0, Arg2, partCount(Arg0, Arg1)); }

72     void test_case_1() { string Arg0 = "ANTIDISESTABLISHMENTARIANISM"; string Arg1 = "ESTABLISHMENT"; int Arg2 = -1; verify_case(1, Arg2, partCount(Arg0, Arg1)); }

73     void test_case_2() { string Arg0 = "TOPCODERDOTCOM"; string Arg1 = "TOMTMODERDOTCOM"; int Arg2 = 5; verify_case(2, Arg2, partCount(Arg0, Arg1)); }

74     void test_case_3() { string Arg0 = "HELLO"; string Arg1 = "HELLOHEHELLOLOHELLO"; int Arg2 = 5; verify_case(3, Arg2, partCount(Arg0, Arg1)); }

75     void test_case_4() { string Arg0 = "DONTFORGETTHEEMPTYCASE"; string Arg1 = ""; int Arg2 = 0; verify_case(4, Arg2, partCount(Arg0, Arg1)); }

76     void test_case_5() { string Arg0 = "BAAABA"; string Arg1 = "BAAABAAA"; int Arg2 = 2; verify_case(5, Arg2, partCount(Arg0, Arg1)); }

77     void test_case_6() { string Arg0 = "ABBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABB"; string Arg1 = "BBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABAA"; int Arg2 = 17; verify_case(6, Arg2, partCount(Arg0, Arg1)); }

78 

79 // END CUT HERE

80 

81 };

82 // BEGIN CUT HERE

83 int main()

84 {

85         WordParts ___test;

86         ___test.run_test(-1);

87         return 0;

88 }

89 // END CUT HERE

别人的代码

  1 // BEGIN CUT HERE

  2 

  3 // END CUT HERE

  4 #include <functional>

  5 #include <algorithm>

  6 #include <stdexcept>

  7 #include <iostream>

  8 #include <sstream>

  9 #include <fstream>

 10 #include <iomanip>

 11 #include <cstdlib>

 12 #include <cstring>

 13 #include <utility>

 14 #include <cctype>

 15 #include <vector>

 16 #include <string>

 17 #include <bitset>

 18 #include <queue>

 19 #include <stack>

 20 #include <ctime>

 21 #include <list>

 22 #include <map>

 23 #include <set>

 24 #include <math.h>

 25 

 26 using namespace std;

 27 

 28 #define ll long long

 29 #define MOD 1000000007

 30 

 31 class WordParts

 32 {

 33         public:

 34         string comp;

 35         vector <string> dic;

 36         int m[100];

 37 

 38         int r(int pos)

 39         {

 40             int &ret = m[pos];

 41 

 42             if (m[pos] != -1)

 43                 return m[pos];

 44 

 45             if (pos == comp.size())

 46                 return 0;

 47 

 48              ret = 10000;

 49 

 50             for (int i=0; i<dic.size(); i++)

 51                 if (comp.substr(pos, dic[i].size()) == dic[i])

 52                     ret = min(ret, 1 + r(pos+dic[i].size()));

 53 

 54             return ret;

 55         }

 56 

 57         int partCount(string original, string compound)

 58         {

 59             int ret = 0;

 60             comp = compound;

 61             memset(m, -1, sizeof(m));

 62 

 63             for (int i=0; i<original.size(); i++)

 64             {

 65                 if (i != 0) {

 66                     dic.push_back(original.substr(0, i));

 67                 }

 68                 dic.push_back(original.substr(i));

 69             }

 70 

 71             ret = r(0);

 72 

 73             if (ret > 1000)

 74                 ret = -1;

 75 

 76             return ret;

 77         }

 78 

 79 // BEGIN CUT HERE

 80     public:

 81     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); }

 82     private:

 83     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }

 84     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }

 85     void test_case_0() { string Arg0 = "ANTIDISESTABLISHMENTARIANISM"; string Arg1 = "ANTIDISIANISMISM"; int Arg2 = 3; verify_case(0, Arg2, partCount(Arg0, Arg1)); }

 86     void test_case_1() { string Arg0 = "ANTIDISESTABLISHMENTARIANISM"; string Arg1 = "ESTABLISHMENT"; int Arg2 = -1; verify_case(1, Arg2, partCount(Arg0, Arg1)); }

 87     void test_case_2() { string Arg0 = "TOPCODERDOTCOM"; string Arg1 = "TOMTMODERDOTCOM"; int Arg2 = 5; verify_case(2, Arg2, partCount(Arg0, Arg1)); }

 88     void test_case_3() { string Arg0 = "HELLO"; string Arg1 = "HELLOHEHELLOLOHELLO"; int Arg2 = 5; verify_case(3, Arg2, partCount(Arg0, Arg1)); }

 89     void test_case_4() { string Arg0 = "DONTFORGETTHEEMPTYCASE"; string Arg1 = ""; int Arg2 = 0; verify_case(4, Arg2, partCount(Arg0, Arg1)); }

 90     void test_case_5() { string Arg0 = "BAAABA"; string Arg1 = "BAAABAAA"; int Arg2 = 2; verify_case(5, Arg2, partCount(Arg0, Arg1)); }

 91     void test_case_6() { string Arg0 = "ABBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABB"; string Arg1 = "BBBAABABBBAABBABBABABBABAABBAABBBBBABBABABBABAABAA"; int Arg2 = 17; verify_case(6, Arg2, partCount(Arg0, Arg1)); }

 92 

 93 // END CUT HERE

 94 

 95 };

 96 // BEGIN CUT HERE

 97 int main()

 98 {

 99         WordParts ___test;

100         ___test.run_test(-1);

101         return 0;

102 }

103 // END CUT HERE

 

你可能感兴趣的:(topcoder)