题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12588
在判断 ‘+’ 的时候使用了 重叠度 的概念,跟一般的 “先去掉这个位置,看剩下的位置能不能符合条件” 方法不太一样。
代码如下:
#include <algorithm> #include <numeric> #include <iterator> #include <functional> #include <iostream> #include <sstream> #include <string> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cctype> #include <climits> #include <cmath> #include <cstring> using namespace std; /************** Program Begin *********************/ const int MAX = 50; int flag[MAX]; class SurveillanceSystem { public: string getContainerInfo(string containers, vector <int> reports, int L) { string res(containers.size(), '-'); vector < vector<int> > pos( containers.size()+1 ); // pos[c]表示能够监视到c个'X'的所有的位置的起始处 vector <int> rep_count( L+1 ); // rep_count[c]表示,reports中c出现的次数 for (int i = 0; i <= containers.size()-L; i++) { int c = count(&containers[i], &containers[i]+L, 'X'); // 计算各个位置能监视到的'X' pos[c].push_back(i); } for (int i = 0; i < reports.size(); i++) { ++rep_count[ reports[i] ]; } for (int i = 0; i <= L; i++) { int rc = rep_count[i]; if (rc == 0) { continue; } // 表示i在reports中出现rc次,而满足可以监视到i个'X'的段保存在pos[i]中, // 一共有pos[i].size个这样的段,也就是要从中选出rc个段,使用每个位置的 // 重叠度来判断该位置是否一定会被监视到。位置的重叠度表示该位置在 // pos[i].size个段中出现的次数。如果其出现次数大于pos[i].size-rc,则 // 这个位置一定会被监视到。因为如果这个位置没有被监视的话,那么找不符合 // 条件的rc个段。 memset(flag, 0, sizeof(flag)); for (int j = 0; j < pos[i].size(); j++) { for (int k = 0; k < L; k++) { if ('-' == res[ pos[i][j] + k ]) { // 在段中出现的位置置为'?' res[ pos[i][j] + k ] = '?'; } ++flag[ pos[i][j]+k ]; // 该位置重叠度加1 } } for (int j = 0; j < containers.size(); j++) { if (flag[j] > pos[i].size() - rc) { //判断重叠度,判断该位置是否必定被监视 res[j] = '+'; } } } return res; } }; /************** Program End ************************/