HDU 6396 - Swordsman [2018杭电多校联赛第七场](优先队列)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6396

【题意】
打怪兽,主角有k个技能,每个技能有对应的攻击力v[i],怪兽有k个防御值a[i],k个强化能量b[i]只有所有的ai >= bi,这只怪兽才会被打死,然后主角的所有技能就会被强化,新的a[i]=打死怪兽前的a[i] +b[i]

问最多能打死多少怪兽,并且最后的v[i]是多少
(1<=n<=1e5 ,k<=5,sum{b[i]+v[i]}<1e9)

【思路】
因为k最大是5,所以可以开5个优先队列来做,每个优先队列去筛选一种技能,技能值大于等于怪兽的防御时将它放入下一个优先队列,直到怪物从最后一个优先队列中弹出说明可以杀死这只怪物,这道题要用加强版的输入输出挂.

#include
namespace IO {
    const int MX = 4e7;
    char buf[MX]; int c, sz;
    void begin() {
        c = 0;
        sz = fread(buf, 1, MX, stdin);
    }
    inline bool read(int &t) {
        while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;
        if(c >= sz) return false;
        bool flag = 0; if(buf[c] == '-') flag = 1, c++;
        for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';
        if(flag) t = -t;
        return true;
    }
}
using namespace std;
using namespace IO;
typedef pair<int,int> pii;
const int maxn=100050;

int n,k;
int v[6];
int a[maxn][6],b[maxn][6];
priority_queuevector,greater > que[6];

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    begin();
    int T;
    read(T);
    while(T--){
        read(n);
        read(k);
        for(int i=1;i<=k;++i) read(v[i]);
        for(int i=1;i<=n;++i){
            for(int j=1;j<=k;++j) read(a[i][j]);
            for(int j=1;j<=k;++j) read(b[i][j]);
        }
        for(int i=0;i<6;++i){
            while(que[i].size()) que[i].pop();
        }
        for(int i=1;i<=n;++i) que[1].push(pii(a[i][1],i));
        int cnt=0;
        bool finish=false;
        while(!finish){
            finish=true;
            for(int j=1;j<=k;++j){
                while(que[j].size()){
                    int val=que[j].top().first;
                    int id=que[j].top().second;
                    if(val>v[j]) break;
                    que[j].pop();
                    if(j==k){
                        finish=false;
                        ++cnt;
                        for(int i=1;i<=k;++i) v[i]+=b[id][i];
                    }
                    else{
                        que[j+1].push(pii(a[id][j+1],id));
                    }
                }
            }
        }
        printf("%d\n",cnt);
        for(int i=1;i<=k;++i){
            printf("%d",v[i]);
            if(i==k) putchar('\n');
            else putchar(' ');
        }
    }
    return 0;
}

你可能感兴趣的:(数据结构-----优先队列)