http://acm.hdu.edu.cn/showproblem.php?pid=6396
我们将每个怪物的属性都分离开来,这样我们就得到5个数组,然后每个数组里都要记录一下该属性是哪只怪物的。
然后将这5个数组从小到大排序5次。
然后用5个指针去跑这5个数组,只要相应的属性大于当前属性,就将该属性对应的怪物的属性数量-1
如果某种怪物的属性减到0的话。就让主角的属性加上该怪物的奖励。
如果发现。这5个数组的最上面的属性都比主角的属性高,那么意味着主角已经不能再消灭某些怪物的属性了。
那么就输出答案了。
时间复杂度为 nlogn 因为排序
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
const int mod=1e9+7;
struct node
{
int w,id;
}a[10][maxn];
int b[10][maxn];
bool cmp(node a,node b)
{
return a.w<b.w;
}
#define FI(n) FastIO::read(n)
namespace FastIO {
const int SIZE = 1 << 16;
char buf[SIZE], obuf[SIZE], str[60];
int bi = SIZE, bn = SIZE, opt;
int read(char *s) {
while (bn) {
for (; bi < bn && buf[bi] <= ' '; bi++);
if (bi < bn) break;
bn = fread(buf, 1, SIZE, stdin);
bi = 0;
}
int sn = 0;
while (bn) {
for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
if (bi < bn) break;
bn = fread(buf, 1, SIZE, stdin);
bi = 0;
}
s[sn] = 0;
return sn;
}
bool read(int& x) {
int n = read(str), bf;
if (!n) return 0;
int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
if (bf < 0) x = -x;
return 1;
}
};
int w[10];
int num[10];
int n,k;
int vis[maxn];
int main()
{
int T;
FI(T);
while(T--)
{
FI(n);
FI(k);
for(int i=1;i<=k;i++)
{
num[i]=1;
FI(w[i]);
}
for(int i=1;i<=n;i++)
vis[i]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
FI(a[j][i].w);
a[j][i].id=i;
}
for(int j=1;j<=k;j++)
{
FI(b[j][i]);
}
}
for(int i=1;i<=k;i++)
sort(a[i]+1,a[i]+1+n,cmp);
int sum=0;
while(1)
{
int f=0;
for(int i=1;i<=k;i++)
{
while(num[i]<=n&&a[i][num[i]].w<=w[i])
{
int z=a[i][num[i]].id;
vis[z]++;
if(vis[z]==k)
{
f=1;
sum++;
for(int i=1;i<=k;i++)
w[i]+=b[i][z];
}
num[i]++;
}
}
if(!f)break;
}
printf("%d\n",sum);
for(int i=1;i<=k;i++)
{
if(i>1)printf(" ");
printf("%d",w[i]);
}
printf("\n");
}
return 0;
}