bjfu1099 度度熊大战僵尸

这也是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 = 11;
int N, K;
int a[maxn], b[maxn];
int buf[51000];
set<int> S;

const int maxh = 1000007;
bool hash[maxh];
int hval[maxh];

void hash_insert(int num) {
    int k = num % maxh;
    while (hash[k] && hval[k] != num) {
        k = (k + 1) % 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 + 1) % maxh;
    }
    return hash[k];
}

int work() {
    bool hasnew = true;
    S.insert(0);
    hash_insert(0);
    int offset, I;
    for (int t = 1; t <= K; t++) {
        if (hasnew) {
            I = 0;
            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 = 0; i < N; i++) {
            a[i] += b[i];
            if (a[i] > offset) {
                continue;
            }
            for (int j = 0; 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 = 0; i < N; i++) {
        scanf("%d%d", &a[i], &b[i]);
    }
    printf("%d\n", work());
    return 0;
}
时间: 2024-10-12 03:11:11

bjfu1099 度度熊大战僵尸的相关文章

苹果IOS,与windows Phone7,系统,内存,CPU处理,及后台程序运行,详解微软墓碑机制的系统

关于ios的多任务以及内存管理 看了很多人为自己的可用内存是350mb还是380mb纠结.为了多优化出一点可用内存费脑筋. ios的任务管理和内存管理,跟windows是有很大差别的.很多人习惯于用 windows的思维去看待ios. windows大家都知道,窗口开的越多,系统越慢,为什么呢?因为所有窗口都在运行,cpu占用率高:并且都占内存.可用内存不足还会迫使系统使用硬盘充当虚拟内存,硬盘频繁读写当然会多耗电,并且硬盘速度也比较慢. ios则不同.首先ios的后台任务,除了极少数可以后台运

DDoS攻防战 (一) : 概述

岁寒 然后知松柏之后凋也 --论语·子罕 (此图摘自<Web脚本攻击与防御技术核心剖析>一书,作者:郝永清先生)    DDoS,即 Distributed Denial of Service ,可译为分散式阻断服务攻击. 上图与DDoS的字面已经清楚的表述出了此类攻击的原理,勿需多言.这类攻击泛滥存在的主要原因之一是网络服务的开放性,这一特点导致了DDoS攻击无法根本杜绝,目前主要应对策略是积极防御与消极防御. 典型DDoS的攻击方式:     ·死亡之Ping icmp封装于IP报文之中,

植物大战僵尸2天空之城安卓版发布

全体注意!一大波飞行僵尸正在接近中——中国独创版<植物大战僵尸2天空之城>安卓版终于发布了.超乎想象的空战体验.全新僵尸植物军团.独特闪电环境效果和史无前例的战舰成长系统,让你和戴夫共同肩负守卫天空之城的荣耀重任.赶紧下载游戏,加入云端激战吧. <植物大战僵尸2天空之城>安桌版上线 [中国区独有版本 打造铿锵空战体验] <植物大战僵尸2>即将迎来两周年生日,为感谢中国玩家一直以来的热情支持,EA/PopCap携手拓维游戏打造了这款中国区独有新版本<植物大战僵尸2天

R-EACTR:一个设计现实网络战演习的框架

本材料来源于国防部资助并由卡内基梅隆大学软件工程研究所的运营的项目,合同编号为FA8721-05-C-0003,该项目是一家联邦资助的研究与开发中心. 本材料中所表达的任何意见.调查结果和结论或建议均为委托人的意见,调查结果和结论或建议,并不一定反映美国国防部的观点. 无担保.卡内基梅隆大学和软件工程学院的材料是"按原样"提供的.卡内基梅隆大学不作任何明示或暗示的保证,包括但不限于对适用性或适销性.专有性或使用本材料所产生的结果的担保.卡内基梅隆大学也不会对任何由此所产生的关于专利.商

来论 | 金融战就跟熬鹰一样,谁先熬不住谁输

https://mp.weixin.qq.com/s?__biz=MjM5OTY4NjAwMQ==&mid=2650093688&idx=1&sn=da87cc142e9e3d1f459d5b7d6517fa63&chksm=bf3622668841ab705267abd653c00c7c442f74b11bc8202150df4b2375abf0167e8355aaeb3b&scene=0#rd 刘安民   6月20日 中美贸易大战,看得大家心嘭嘭直跳.但是说实话

未来的DDoS 攻击战

一.未来的网络战 未来的网络战会同时表现出两种趋势:更广泛的打击和更精确的打击.更广泛的打击是指将敌对国家整体作为打击目标,通过制造社会混乱来降低对手的抵抗.战争爆发的同时,金融系统数据会突然出现混乱,各种交易无法进行:智能电网瘫痪,电力供应中断导致生产停滞:交通调度系统也陷入失控状态,城里的人无法出去,城外的物资无法进入:电话和网络中断,电视广播只能收到敌对台的宣传.这里描述的场景非幻想,其中的每种现象都是攻击者当前就可以通过网络攻击来实现的.例如,2008年俄罗斯和格鲁吉亚的战争中,格鲁吉亚

c编程:僵尸吃大脑

第一行输入一个正整数n 以下每一行输入僵尸已经吃了的大脑数量a,和需要生存必需要吃的大脑数量b.总共n行. 例子输入 3 4 5 3 3 4 3 例子输出 NO BRAINS MMM BRAINS MMM BRAINS 即假设a>=b即输出MMM BRAINS(僵尸能活) 否则输出     NO BRAINS(僵尸不能活下来) 代码: //僵尸吃大脑 #include<stdio.h> int main() { int n; int i; int a,b; int m[20]={0};

【NOI2009】植物大战僵尸

P1589 - [NOI2009]植物大战僵尸 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而 Zombies进攻.该款游戏包含多种不同的挑战系列,比如Protect Your Brain.Bowling等等.其中最为经典的,莫过于玩家通过控制Plants来防守Zombies的进攻,或者相反地由玩家通过控制Zombies 对Plants发起进攻. 现在,我们将要考

第十九篇:处理僵尸进程的两种经典方法

前言 如果父进程没有结束,而子进程终止了.那么在父进程调用 wait 函数回收这个子进程或者父进程终止以前,这个子进程将一直是僵尸进程. 本文将提供两种方法处理这个问题. 方法一:父进程回收法 wait函数将使其调用者阻塞,直到其某个子进程终止.故父进程可调用wait函数回收其僵尸子进程.除此之外,waitpid函数提供更为详尽的功能( 增加了非阻塞功能以及指定等待功能 ),请读者自行查阅相关资料. 代码实现 1 #include <unistd.h> 2 #include <sys/w