题目链接<http://acm.hdu.edu.cn/showproblem.php?pid=6396>
题意:
一共有n只怪物,每个怪物都有k个属性。如果你的每个属性都高于怪物的,那你就可以把它杀死,你的属性也能获得相应的提升。问你最多能杀死几只怪物,和最后的自身属性。
题解:
这题时间卡的非常紧,一定一定一定要用优秀的输入挂。
设k个数组记录对应的怪物id和对应的属性大小,每个属性按照从小到大的顺序排列。
再设k个坐标,表示每个属性能取到的范围,并进行标记。因为自身的属性只会增大,坐标也只会向右走。
如果某一个怪物每个属性都被标记过了。那这只怪物就是可以被杀死的,自身的属性就增加。
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+7;
const int inf=1<<26;
struct Node{
int id,val;
Node(int id=0,int val=0):id(id),val(val){}
bool operator<(const Node a)const{
return this->val<a.val;
}
}c[10][N];
int a[N][10],b[N][10],now[10];
bool vis[N];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int _read(){
char ch=nc();int sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
return sum;
}
int pos[10],cnt[N];
int main()
{
int t,n,k;
t=_read();
while(t--){
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
n=_read();k=_read();
for(int i=1;i<=k;i++)
now[i]=_read();
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
a[i][j]=_read();
c[j][i].id=i;
c[j][i].val=a[i][j];
}
for(int j=1;j<=k;j++)
b[i][j]=_read();
}
for(int i=1;i<=k;i++){
sort(c[i]+1,c[i]+1+n);
pos[i]=1;
}
int ans=0;
while(1){
bool ok=false;
for(int j=1;j<=k;j++){
while(pos[j]<=n){
int u=c[j][pos[j]].id;
if(now[j]>=a[u][j]){
cnt[u]++;
if(cnt[u]==k){
ans++; ok=true;
for(int x=1;x<=k;x++)
now[x]+=b[u][x];
}
pos[j]++;
}
else break;
}
}
if(ok==false) break;
}
printf("%d\n",ans);
for(int i=1;i<=k;i++){
if(i!=1) printf(" ");
printf("%d",now[i]);
}
printf("\n");
}
return 0;
}