SRM 581 D2 L2:SurveillanceSystem,重叠度

题目来源: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 ************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值