1. 给定一个m*n的数组(m,n>=2,数组值>=0),要求选出和最大的子2*2数组。例如:
1 2 3
4 5 6
7 8 9
显然和最大的2*2子数组是5 6;8 9.下面完成这个功能。
Input: (m*n的数组)
1 2 3 ; 4 5 6 ; 7 8 9
Output: (最大的和)
28
解析:这个问题我觉得有两个难点,第一个就是二维数组的生成,初始时刻给了我们一行字符串,格式如上。我们需要从中读取二维数组,第二个就是核心算法,这里我们使用暴力解法,两行两列地逐步向后向下推进,直到找到最大的和。
代码:
#include <iostream> #include <vector> #include <string> #include <stdio.h> using namespace std; vector<string> split( string str, string pattern)//分割字符串,分隔符是pattern { vector<string> result; str += pattern;//扩张字符串以方便操作 string::size_type pos; int n = str.size(); for (int i = 0; i < n;i++) { pos = str.find(pattern, i); if (pos<n) { string s = str.substr(i, pos - i ); result.push_back(s); i = pos +pattern.size()- 1; } } return result; } int main() { //读取二维数组 string str; getline(cin, str); vector<string> vecstr = split(str, ";");//第一次分割 int m = vecstr.size();//m行 int n;//列数 vector<vector<int> > arr(m); for (int i = 0; i < m;i++) { vector<string> vecstr2 = split(vecstr[i]," "); n = vecstr2.size(); arr[i].reserve(n); for (int j = 0; j < n; j++) { arr[i].push_back(atoi(vecstr2[j].c_str())); } } //找到最大的和 int maxsum = 0; int row , column ; for (int i = 0; i < m - 1; i++) for (int j = 0; j < n - 1; j++) { int sum = arr[i][j] + arr[i][j + 1] + arr[i + 1][j] + arr[i + 1][j + 1]; if (maxsum < sum) { row = i; column = j; maxsum = sum; } } cout << "最大的子数组是:" << endl; cout << arr[row][column] << "\t" << arr[row][column + 1] << endl; cout << arr[row + 1][column] << "\t" << arr[row + 1][column + 1] << endl; cout << "最大的和是" << maxsum << endl; }结果:
2.已知有一个数组,有正数、负数、0,要求输出和为0的最长连续子数组。
Input: -1 0 1 2 -1 -2 3 4 -4
Output: 0 1 2 -1 -2
解析:
定义i,j,让i从前往后遍历,在i确定的时候,让j从后往前遍历,直到遇到第一个为0的时候停下来,计算i,j之间的距离,然后i继续遍历,选最长的即可。同时为了节约时间,一旦有一种情形的长度超过整体长度的一半,则i只需遍历到整体的前一半即可。
代码:
#include <iostream> #include <vector> #include <string> #include <iterator> #include <algorithm> #include <sstream> #include <numeric> using namespace std; typedef vector<int> vecint; vecint max_subarray(string str) { stringstream s(str); vecint data,subdata; data.reserve(str.length()); int t; while (s>>t) { data.push_back(t); } int n = data.size(); int disnum = 0; int low=-1, high=-1; for (int i = 0; i < n;i++) { if (i >= n / 2 && disnum >= n / 2) { break; } int sum = accumulate(data.begin() + i, data.end(), 0); int j = n - 1; while (sum!=0&&j>=i) { sum -= data[j--]; } if (sum == 0 && (disnum<(j - i + 1))) { disnum =j - i + 1;//子数组的长度 low = i; high = j; } } if (disnum!=0) { for (int k = low; k <= high; k++) { subdata.push_back(data[k]); } } return subdata; } int main() { string str; getline(cin, str); vecint subarray = max_subarray(str); if (subarray.empty()) { cout << "there's not such subarray that sum equals to zero" << endl; } else { cout << "Result has founded:" << endl; copy(subarray.begin(), subarray.end(), ostream_iterator<int>(cout, " ")); } }
-1 0 1 2 -1 -2 3 4 -4
Result has founded:
0 1 2 -1 -2 请按任意键继续. . .