这也是2011年百度之星的一道题。

这题我就是乱搞搞过的,打代码之前自己心里也没底,不知道能不能过的。

我的做法很简单,就是按时间顺序依次构造能杀死的僵尸血量,找到第k小的。构造的方法也很暴力:对t时刻,第i个武器新构造出来的血量,就是用ai+t*bi依次去加之前时刻构造出来的血量。所以解题的关键就在于不断地对这个方法进行剪枝与优化。

第一个优化是,t只用从1到k,而不用再往后,很好理解。

第二,考虑如何存储已经产生的血量。我是用了一个set保存所有的血量,然后每一次循环时把set中的内容导出到一个数组里。往set里插入数据和查找数据都是log n的,所以把数据导出到数组里复杂度为n*log(n)。这里又可以加入一个优化,每次导出到数组里的元素只用前K个。

第三个优化,如果当t时刻,所有的ai+bi*t都比当前的结果大,则可以结束。

这样打完之后,自己测了几组数据,很快出结果,但是交上去依然超时。于是自己构造了几组变态数据,一测,发现瓶颈依然在set那里,因为对于大型的测试数据,后来的时刻产生的大量血量值都是以前出现过的,如果用hash来判断血量值是否出现过,就能把这里的复杂度从log(n)降到O(1),因为这里是瓶颈,所以效果很明显。果然,加上以后就过了。

代码如下:

/*
* bjfu1099
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
#ifdef ON_LOCAL_DEBUG
#else
#endif
typedef long long LL;
const int maxn = ;
int N, K;
int a[maxn], b[maxn];
int buf[];
set<int> S; const int maxh = ;
bool hash[maxh];
int hval[maxh]; void hash_insert(int num) {
int k = num % maxh;
while (hash[k] && hval[k] != num) {
k = (k + ) % maxh;
}
if (!hash[k]) {
hash[k] = true;
hval[k] = num;
}
} bool hash_find(int num) {
int k = num % maxh;
while (hash[k] && hval[k] != num) {
k = (k + ) % maxh;
}
return hash[k];
} int work() {
bool hasnew = true;
S.insert();
hash_insert();
int offset, I;
for (int t = ; t <= K; t++) {
if (hasnew) {
I = ;
set<int>::iterator it = S.begin();
while (it != S.end() && I <= K) {
buf[I++] = *(it++);
}
hasnew = false;
}
offset = (I > K) ? buf[K] : 0x7fffffff;
// printf("t = %d, offset = %d, I = %d\n", t, offset, I);
bool flag = false;
for (int i = ; i < N; i++) {
a[i] += b[i];
if (a[i] > offset) {
continue;
}
for (int j = ; j < I; j++) {
int p = a[i] + buf[j];
if (p < offset) {
flag = true;
if (!hash_find(p)) {//对于大型的测试数据,后面的插入太多重复,用hash能降掉这里的logn的复杂度
// if (S.count(p) <= 0) {
hasnew = true;
S.insert(p);
hash_insert(p);
}
} else {
break;;
}
}
}
if (!flag) {
break;
}
}
return buf[K];
} int main() {
#ifdef ON_LOCAL_DEBUG
freopen("data.in", "r", stdin);
#endif
memset(hash, false, sizeof(hash));
scanf("%d%d", &N, &K);
for (int i = ; i < N; i++) {
scanf("%d%d", &a[i], &b[i]);
}
printf("%d\n", work());
return ;
}

最新文章

  1. 清除Android工程中没用到的资源
  2. oracle10g 统计信息查看、收集
  3. Qt之界面出现、消失动画效果(简单好用)
  4. 无聊之作,RPGdemo制作(一)角色state模式
  5. WM_PAINT消息小结
  6. QPS/TPS/并发量/系统吞吐量概念和公式
  7. c# 笔记cookie
  8. [URLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]
  9. goroutine与调度器
  10. [Python]基于K-Nearest Neighbors[K-NN]算法的鸢尾花分类问题解决方案
  11. 自学Python2.1-基本数据类型-字符串str(object) 上
  12. python 全栈开发,Day53(jQuery的介绍,jQuery的选择器,jQuery动画效果)
  13. ThinkPHP 3.1.2 输出和模型使用 配置项等 - 2
  14. 118/119. Pascal&#39;s Triangle/II
  15. Python 内置方法new
  16. Apache Kudu as a More Flexible And Reliable Kafka-style Queue
  17. expdp 简单例子
  18. Winform DatagridviewcomboboxColumn Disable Style
  19. css选择器的性能
  20. New Concept English Two 9 22

热门文章

  1. POJ1008Maya Calendar
  2. 简单易懂的现代魔法&mdash;&mdash;Play Framework攻略3
  3. python对json的相关操作
  4. 爬虫Larbin解析(一)——Larbin配置与使用
  5. OpenCV码源笔记——RandomTrees (一)
  6. MATLAB曲线绘制
  7. iOS方法封装
  8. BZOJ 1297 迷路(矩阵)
  9. Ubuntu下jdk配置
  10. 如何使用UIAutomation进行iOS 自动化测试(Part I)