题意:
有n个怪物,每只怪物都有(有k种防御属性,分别为 ai,1......ai,k),你是主人公,有k种攻击属性 v(1......k)。
当 v[i] >= a[id][i] ,i ∈ [1, k] 时,该怪物可以被杀死,你的攻击属性可以增加 b[id][i],即 v[i] += b[id][i]。
问最多可以杀多少怪物,并且输出最后你的攻击属性。
题解:
我们可以通过优先队列把所有怪物第一个属性放进去,把每一个符合第 i 个条件的怪物的下一个属性放进下一个队列中,再次循环,知道得到 i == k 时就可以更新主人公攻击属性,击杀也可以加一。直到所有都不符合就可以退出了。
第一个样例:
(0,3) | -> | (0,4) | -> | (1,4) |
(5,1) | (4,3) | |||
(6,4) | (5,1) | |||
(24,2) |
这样只有第四个符合,所以这时候的攻击属性就为 7+5, 1+3, 1+1 == 12, 4, 2。
(24,2) | -> | (4,3) | -> | (1,3) |
(5,1) | ||||
这样只有第三个符合,所以这时候的攻击属性就为 12+5, 4+1, 2+1 == 17, 5, 3。
(24,2) | -> | (5,1) | -> | (1,1) |
这样只有第一个符合,所以这时候的攻击属性就为 17+6, 5+3, 3+1 == 23, 8, 4。
最后因为 队列一的头是 24 大于 23,其他队列是空的,所以已经没有符合条件的怪兽就退出输出答案即可。
不过,这道题的输入有点秀的,我也是看别人的代码才知道要优化输入,这就很嘤嘤嘤了。
输入模板:
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;
}
}
ac代码:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <stack>
#include <cmath>
#include <deque>
#include <queue>
#include <list>
#include <set>
#include <map>
#define mem(a) memset(a, 0, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;
priority_queue <pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q[10];
int v[10], monster[500010][30];
/*
百度之星的优化输入模板 还是超时 0.0
void read(int &x){
char ch = getchar();x = 0;
for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}
*/
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;
}
}
int main(){
IO::begin();
int t;
IO::read(t);
while(t--){
int n, k;
IO::read(n);
IO::read(k);
for(int i = 1; i <= k; i++){
IO::read(v[i]);
while(!q[i].empty()){
q[i].pop();
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= 2*k; j++){
IO::read(monster[i][j]);
if(j == 1){
q[1].push(make_pair(monster[i][j], i));
}
}
}
int ok = 0, cnt = 0;
while(!ok){
ok = 1;
for(int i = 1; i <= k; i++){
while(!q[i].empty()){
if(v[i] < q[i].top().first){
break;
}
if(i == k){
cnt++;
ok = 0;
int id = q[i].top().second;
for(int j = 1; j <= k; j++){
v[j] += monster[id][k+j];
}
q[i].pop();
}
else{
int id = q[i].top().second;
q[i].pop();
q[i+1].push(make_pair(monster[id][i+1], id));
}
}
}
}
printf("%d\n", cnt);
for(int i = 1; i <= k; i++){
printf("%d%c", v[i], i == k ? '\n' : ' ');
}
}
}