SRM 513 2 1000CutTheNumbers
Problem Statement
Manao has a board filled with digits represented as String[] board. The j-th character of the i-th element of board represents the digit written in cell in row i, column j of the board. The rows are numbered from top to bottom and the columns are numbered from left to right.
Manao is going to cut it into several non-overlapping fragments. Each of the fragments will be a horizontal or vertical strip containing 1 or more elements. A strip of length N can be interpreted as an N-digit number in base 10 by concatenating the digits on the strip in order. The horizontal strips are read from left to right and the vertical strips are read from top to bottom. The picture below shows a possible cutting of a 4x4 board:
The sum of the numbers on the fragments in this picture is 493 + 7160 + 23 + 58 + 9 + 45 + 91 = 7879.
Manao wants to cut the board in such a way that the sum of the numbers on the resulting fragments is the maximum possible. Compute and return this sum.
Definition
- ClassCutTheNumbers
- MethodmaximumSum
- Parametersvector<string>
- Returnsint
- Method signatureint maximumSum(vector<string> board)
(be sure your method is public)
Limits
- Time limit (s)2.000
- Memory limit (MB)64
Notes
- The numbers on the cut strips are allowed to have leading zeros. See example #2 for details.
Constraints
- board will contain between 1 and 4 elements, inclusive.
- board[0] will be between 1 and 4 characters long, inclusive.
- Each element of board will be of the same length as board[0].
- Each character in board will be a decimal digit (‘0‘-‘9‘).
Test cases
-
- board{"123",
"312"}
Returns435
Manao can cut out both rows in whole, obtaining 123 + 312 = 435. He also could cut the columns one by one for a total of 66, or cut the first column and the residual rows one by one, obtaining 13 + 23 + 12 = 48, or even cut out single elements, but would not get a better sum.
- board{"123",
-
- board{"99",
"11"}
Returns182
It‘s better to cut out the whole columns.
- board{"99",
-
- board{"001",
"010",
"111",
"100"}
Returns1131
The numbers on the strips may have leading zeros. Cutting the columns in whole, Manao obtains 0011 + 0110 + 1010 = 1131.
- board{"001",
-
- board{ "8" }
Returns8
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.
你可以认为0的话,就是向左连,1的话就是向下连。
然后状态压缩一下。枚举所有的状态即可。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <ctime> 5 #include <iostream> 6 #include <algorithm> 7 #include <set> 8 #include <vector> 9 #include <sstream> 10 #include <typeinfo> 11 #include <fstream> 12 13 using namespace std; 14 const int inf = 0x3f3f3f3f ; 15 int n , m ; 16 int maxn ; 17 int path[5] ; 18 vector<int> b[10] ; 19 class CutTheNumbers { 20 public: 21 int maximumSum(vector<string> board) { 22 n = board.size () ; 23 m = board[0].size () ; 24 for (int i = 0 ; i < n ; i ++) b[i].clear () ; 25 for (int i = 0 ; i < n ; i ++) { 26 for (int j = 0 ; j < m ; j ++) { 27 b[i].push_back( board[i][j] - ‘0‘ ); 28 } 29 } 30 maxn = - inf ; 31 dfs (0) ; 32 return maxn ; 33 } 34 35 void dfs (int dep) { 36 if (dep == n) { 37 solve () ; 38 return ; 39 } 40 for (int i = 0 ; i < (1 << m) ; i ++) { 41 path[dep] = i ; 42 dfs (dep + 1) ; 43 } 44 } 45 46 void solve () { 47 bool map[5][5] ; 48 int ans = 0 ; 49 memset (map , 0 , sizeof(map) ) ; 50 51 for (int i = 0 ; i < n ; i ++) { 52 int j = 0 ; 53 int tmp = path[i] ; 54 while (tmp) { 55 map[i][j ++] = tmp & 1 ; 56 tmp>>= 1 ; 57 } 58 reverse (map[i] , map[i] + m) ; 59 } 60 61 bool mark[5][5] ; 62 memset (mark , 0 , sizeof(mark) ) ; 63 64 for (int i = 0 ; i < n ; i ++) { 65 for (int j = 0 ; j < m ; j ++) { 66 if (!mark[i][j]) { 67 int tmp = 0 ; 68 if (!map[i][j]) { 69 for (int k = j ; k < m && !map[i][k] ; k ++) { 70 mark[i][k] = 1 ; 71 tmp = tmp * 10 + b[i][k] ; 72 } 73 } 74 else { 75 for (int k = i ; k < n && map[k][j] ; k ++) { 76 mark[k][j] = 1 ; 77 tmp = tmp * 10 + b[k][j] ; 78 } 79 } 80 ans += tmp ; 81 } 82 } 83 } 84 maxn = max (maxn , ans) ; 85 } 86 87 88 }; 89 90 // CUT begin 91 ifstream data("CutTheNumbers.sample"); 92 93 string next_line() { 94 string s; 95 getline(data, s); 96 return s; 97 } 98 99 template <typename T> void from_stream(T &t) { 100 stringstream ss(next_line()); 101 ss >> t; 102 } 103 104 void from_stream(string &s) { 105 s = next_line(); 106 } 107 108 template <typename T> void from_stream(vector<T> &ts) { 109 int len; 110 from_stream(len); 111 ts.clear(); 112 for (int i = 0; i < len; ++i) { 113 T t; 114 from_stream(t); 115 ts.push_back(t); 116 } 117 } 118 119 template <typename T> 120 string to_string(T t) { 121 stringstream s; 122 s << t; 123 return s.str(); 124 } 125 126 string to_string(string t) { 127 return "\"" + t + "\""; 128 } 129 130 bool do_test(vector<string> board, int __expected) { 131 time_t startClock = clock(); 132 CutTheNumbers *instance = new CutTheNumbers(); 133 int __result = instance->maximumSum(board); 134 double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC; 135 delete instance; 136 137 if (__result == __expected) { 138 cout << "PASSED!" << " (" << elapsed << " seconds)" << endl; 139 return true; 140 } 141 else { 142 cout << "FAILED!" << " (" << elapsed << " seconds)" << endl; 143 cout << " Expected: " << to_string(__expected) << endl; 144 cout << " Received: " << to_string(__result) << endl; 145 return false; 146 } 147 } 148 149 int run_test(bool mainProcess, const set<int> &case_set, const string command) { 150 int cases = 0, passed = 0; 151 while (true) { 152 if (next_line().find("--") != 0) 153 break; 154 vector<string> board; 155 from_stream(board); 156 next_line(); 157 int __answer; 158 from_stream(__answer); 159 160 cases++; 161 if (case_set.size() > 0 && case_set.find(cases - 1) == case_set.end()) 162 continue; 163 164 cout << " Testcase #" << cases - 1 << " ... "; 165 if ( do_test(board, __answer)) { 166 passed++; 167 } 168 } 169 if (mainProcess) { 170 cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl; 171 int T = time(NULL) - 1436409000; 172 double PT = T / 60.0, TT = 75.0; 173 cout << "Time : " << T / 60 << " minutes " << T % 60 << " secs" << endl; 174 cout << "Score : " << 1000 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl; 175 } 176 return 0; 177 } 178 179 int main(int argc, char *argv[]) { 180 cout.setf(ios::fixed, ios::floatfield); 181 cout.precision(2); 182 set<int> cases; 183 bool mainProcess = true; 184 for (int i = 1; i < argc; ++i) { 185 if ( string(argv[i]) == "-") { 186 mainProcess = false; 187 } else { 188 cases.insert(atoi(argv[i])); 189 } 190 } 191 if (mainProcess) { 192 cout << "CutTheNumbers (1000 Points)" << endl << endl; 193 } 194 return run_test(mainProcess, cases, argv[0]); 195 } 196 // CUT end