题意:
给出k种属性,一个人的k种属性有初始值为,他要去打n个怪兽,第i个怪兽也有k种属性,如果当前的,这个人就可以打第i个怪兽,并且每个属性得到怪兽的加成。问你这个人最多可以打几个怪兽,并输出这个人最后的属性值。
思路:
贪心思路是要打的就打,从a小的开始打,所以先对怪兽的每种属性从小到大排序,拿k个指针去扫,对满足被打条件的属性的怪兽进行标记,当某个怪兽的所有属性都被标记了,就将b加给人,指针向后移动。
这里要用到读入挂。
代码:
int ori[10];
struct node
{
int cost,id;
};
vector<node>v[10];
int cnt[100010];
int val[100010][10];
int pos[10];
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;
}
}
bool cmp(node x,node y)
{
return x.cost<y.cost;
}
int main()
{
IO::begin();
int t,n,k,x;
//scanf("%d",&t);
IO::read(t);
while(t--)
{
//scanf("%d%d",&n,&k);
IO::read(n);IO::read(k);
for(int i=1;i<=k;i++)
{
//scanf("%d",&ori[i]);
IO::read(ori[i]);
v[i].resize(n+1);
pos[i]=0;
}
for(int i=1;i<=n;i++)
{
cnt[i]=0;
for(int j=1;j<=k;j++)
{
//scanf("%d",&x);
IO::read(x);
v[j][i]=node{x,i};
}
for(int j=1;j<=k;j++)
//scanf("%d",&val[i][j]);
IO::read(val[i][j]);
}
for(int i=1;i<=k;i++)
sort(v[i].begin()+1,v[i].begin()+n+1,cmp);
/*for(int i=1;i<=k;i++)
{
for(int j=1;j<=n;j++)
printf("(%d,%d)",v[i][j].cost,v[i][j].id);
printf("\n");
}*/
int tot=0;
while(1)
{
int sign=0;
for(int i=1;i<=k;i++)
{
for(int j=pos[i]+1;j<=n;j++)
{
if(v[i][j].cost<=ori[i])
{
sign++;
cnt[v[i][j].id]++;
if(cnt[v[i][j].id]==k)
{
tot++;
for(int l=1;l<=k;l++)
ori[l]+=val[v[i][j].id][l];
}
pos[i]=j;
}
else break;
}
}
if(sign==0)break;
}
printf("%d\n",tot);
for(int i=1;i<k;i++)
printf("%d ",ori[i]);
printf("%d\n",ori[k]);
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!