#include <iostream> #include <numeric> #include <vector> #include <cmath> using namespace std; const int PN = 10000000; int primes[PN]; vector<int> primelist; void sieve() { primes[0] = 0; primes[1] = 0; primes[2] = 1; for (int i = 3; i < PN; ++i) primes[i] = i % 2; for (int i = 3; i <= int(sqrt(PN*1.0) + 0.5); i += 2) if (primes[i]) for (int j = 2*i; j < PN; j += i) primes[j] = 0; for (int i = 0; i < PN; ++i) if (primes[i]) primelist.push_back(i); } //这个函数的目的是生成素数表,并把素数表添加到Primelist中 void sum(int n, vector<int>& out) { if (primelist.size() < n) return; int cursum = accumulate(primelist.begin(), primelist.begin() + n, 0); out.push_back(cursum); for (int l = 0, r = n; r < primelist.size(); ++r, ++l) { cursum += primelist[r] - primelist[l]; out.push_back(cursum); } } //把所有的n个连续素数的和保存到out中 int main() { sieve(); vector<int> sums[12]; sums[0] = primelist; //copy(primelist.begin(), primelist.begin() + 20, ostream_iterator<int>(cout, " ")); int N; cin >> N; for (int I = 1; I <= N; ++I) { int m; cin >> m; for (int i = 1; i <= m; ++i) { int tmp; cin >> tmp; sums[i].clear(); sum(tmp, sums[i]); } //把结果保存到了sums数组中 int ni[12] = { 0 }; bool success = false; int result = 0; while (!success) { for (int i = 0; i <= m; ++i) { result = max(result, sums[i][ni[i]]); } for (int i = 0; i <= m; ++i) { while (sums[i][ni[i]] < result) ++ni[i]; } success = true; for (int i = 0; i <= m; ++i) { if (sums[i][ni[i]] != result) success = false; } } //这里很巧妙,用了现行推进的算法每次找到最小,同时向前推进.如果最小不相同则又从刚结束的问题推进 cout << "Scenario " << I << ":" << endl; cout << result << endl << endl; } } 很好的一个问题,这个思想真的很重要.首先构造出所有n个连续数和,然后利用一个O(n)的算法找到我们所要求的最小值!