HDU - 6396 - 杭电多校第七场 - Swordsman

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/81635157

题目链接<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;
}

猜你喜欢

转载自blog.csdn.net/monochrome00/article/details/81635157