HDU-6396-Swordsman(文件输入+优先队列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6396

Problem Description

Lawson is a magic swordsman with k kinds of magic attributes v1,v2,v3,…,vk . Now Lawson is faced with n monsters and the i -th monster also has k kinds of defensive attributes ai,1,ai,2,ai,3,…,ai,k . If v1≥ai,1 and v2≥ai,2 and v3≥ai,3 and … and vk≥ai,k , Lawson can kill the i -th monster (each monster can be killed for at most one time) and get EXP from the battle, which means vj will increase bi,j for j=1,2,3,…,k .
Now we want to know how many monsters Lawson can kill at most and how much Lawson's magic attributes can be maximized.

 

Input

There are multiple test cases. The first line of input contains an integer T , indicating the number of test cases. For each test case:
The first line has two integers n and k (1≤n≤105,1≤k≤5 ).
The second line has k non-negative integers (initial magic attributes) v1,v2,v3,…,vk .
For the next n lines, the i -th line contains 2k non-negative integers ai,1,ai,2,ai,3,…,ai,k,bi,1,bi,2,bi,3,…,bi,k .
It's guaranteed that all input integers are no more than 109 and vj+∑i=1nbi,j≤109 for j=1,2,3,…,k .

It is guaranteed that the sum of all n ≤5×105 .
The input data is very large so fast IO (like `fread`) is recommended.

 

Output

For each test case:
The first line has one integer which means the maximum number of monsters that can be killed by Lawson.
The second line has k integers v′1,v′2,v′3,…,v′k and the i -th integer means maximum of the i -th magic attibute.

 

Sample Input

 

1 4 3 7 1 1 5 5 2 6 3 1 24 1 1 1 2 1 0 4 1 5 1 1 6 0 1 5 3 1

 

Sample Output

 
3 23 8 4

Hint

For the sample, initial V = [7, 1, 1] ① kill monster #4 (6, 0, 1), V + [5, 3, 1] = [12, 4, 2] ② kill monster #3 (0, 4, 1), V + [5, 1, 1] = [17, 5, 3] ③ kill monster #1 (5, 5, 2), V + [6, 3, 1] = [23, 8, 4] After three battles, Lawson are still not able to kill monster #2 (24, 1, 1) because 23 < 24.

题目大意:一个k系法师,他的每种元素都有一个法强vi,他碰见 了n个怪物,第i个怪物对每种魔法有着自己的魔抗a[i][k];

大法师只有所有元素的法强都大于怪物对应的法强的时候才会击杀怪物

大法师每次击杀一个怪物,会得到怪物的经验,经验会提升大法师不同元素的法强,问大法师最多能有多少法强。

read()函数的板子:https://blog.csdn.net/qq_37632935/article/details/81665581

输入太多,用read()函数读(这道题本身就是read的板子),至于打怪升级这件事,开五个优先队列,每个优先队列存入怪物的魔抗+ID(k不是五的其他的按0计算),遍历五个优先队列,对于能被击破魔抗的ID 加一,并将它移除队列,如果最后ID==5则这只怪物能被击杀,直接进行经验加成,最后一只怪物都杀不了时结束循环

ac;

//一页 27行就很舒服 
#include<stdio.h>
#include<string.h>  
#include<math.h>  
  
//#include<map>   
//#include<set>
#include<deque>  
#include<queue>  
#include<stack>  
#include<bitset> 
#include<string>  
#include<fstream>
#include<iostream>  
#include<algorithm>  
using namespace std;  

#define ll long long  
#define INF 0x3f3f3f3f  
#define mod 998244353
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b) 
#define clean(a,b) memset(a,b,sizeof(a))// 水印 
//std::ios::sync_with_stdio(false);

//需要自己写文件读入scanf和getchar()都不能用。
//freopen("1.txt","r",stdin);
namespace fastIO {
    #define BUF_SIZE 100000
    //fread -> read
    bool IOerror = 0;
    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if(p1 == pend) {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1) {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }
    inline bool blank(char ch) {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    inline void read(int &x) {
        char ch;
        while(blank(ch = nc()));
        if(IOerror) return;
        for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
    }
    #undef BUF_SIZE
};
using namespace fastIO;

struct node{
    int blood;
    int ID;
    node (int _blood=0,int _ID=0):blood(_blood),ID(_ID){}
    bool operator <(const node &a)const{
        return blood>a.blood;
    }
};
int v[10],ves[100100],arr[100100][6];
int n,k;

priority_queue<node> que[6];

int main()
{
    //freopen("in.txt", "r",stdin);//因为用的是文件读入,因此我们只能在文件中写样例,叫代码的时候要将本地的文件操作注释掉,否则会  WA
    int t;
    read(t);
    while(t--)
    {
        clean(ves,0);
        clean(arr,0);
        clean(v,0);
        read(n);read(k);
        for(int i=1;i<=k;++i)
            read(v[i]);
        for(int i=1;i<=n;++i)
        {
            for(int j=1;j<=5;++j)
            {
                int blood;
                if(j<=k)
                {
                    read(blood);
                    que[j].push(node(blood,i));
                }
                else
                    que[j].push(node(0,i));
            }//输入血量 ,ID=i 
            for(int j=1;j<=5;++j)
            {
                int add;
                if(j<=k)
                {
                    read(add);
                    arr[i][j]=add;
                }
                else
                    arr[i][j]=0;
            }//输入经验 
        }//输入完成 
        
        //debug  没有错 
//        for(int i=1;i<=5;++i)
//        {
//            while(que[i].size())
//            {
//                cout<<que[i].top().blood<<" "<<que[i].top().ID<<" |";
//                que[i].pop();
//            }
//            cout<<endl;
//        }
//        for(int i=1;i<=n;++i)
//        {
//            for(int j=1;j<=5;++j)
//                cout<<arr[i][j]<<" ";
//            cout<<endl;
//        }
        
        int sum=0;
        while(1)
        {
            int f=0;
            for(int i=1;i<=5;++i)
            {
                while(que[i].size())
                {
                    node now=que[i].top();
                    if(now.blood<=v[i])
                    {
                        que[i].pop();
                        ves[now.ID]++;
                        if(ves[now.ID]==5)
                        {
                            sum++;
                            f=1;
                            for(int j=1;j<=5;++j)
                                v[j]=v[j]+arr[now.ID][j];
                        }
                    }
                    else
                        break;
                }
//                for(int j=1;j<=n;++j)
//                    cout<<ves[j]<<" ";
//                cout<<endl;
            }
            if(f==0)
                break;
        }
        printf("%d\n",sum);
        for(int i=1;i<k;++i)
            printf("%d ",v[i]);
        printf("%d\n",v[k]);
        for(int i=0;i<6;++i)
        {
            while(que[i].size())
                que[i].pop();
        }
//        cout<<sum<<endl;
//        for(int i=1;i<=k;++i)
//            cout<<v[i]<<" ";
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/81744829