hdu 6396 Swordsman (优先队列+读入挂)

Swordsman

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1782    Accepted Submission(s): 513


 

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 vkai,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,…,vk 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

题意:打小怪兽的题目,主角有k个技能,每个技能有对应的攻击力ai,怪兽有k个防御值bi,k个强化能量ci。只有所有的

ai > = bi,这只小怪兽才会被打死。然后主角的技能就会被强化,新的ai = 打死怪兽前的ai + ci。

问能打死多少怪兽,并且最后的ai是多少。

解法:

1:开了四个优先队列,优先级分别是怪兽第2到k(k <= 5)个防御值。

2:然后先按照k个怪兽防御值的字典序排序,开始遍历这些怪兽,这里的遍历是比较第一个技能和怪兽的第一个防御值,如果技能攻击力大于怪兽的防御值的话,就比较下一个ai+1 和bi+ 1,如果能打死这只小怪兽的话直接把对应的ci加上去。如果ai  < bi,就加入到对应的优先队列里面,即以第i个值为最高优先级的队列。(注意这里要只加入到第一个ai < bi的优先队列里面)。

3:当技能的值发生变化的时候,就要从第一个优先队列的第一个怪兽重新开始比较。

代码写得很长而且很丑,没有用输入挂的时候在T的边缘疯狂试探。

 然后这里要记录一下大佬的超级牛逼的输入挂

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;

用了以后重新试了一下

下面是写的极其丑的代码

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

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;


#define LL long long
#define ui unsigned int
#define uLL unsigned long long
#define scand(x) scanf("%d",&x)
#define scandd(x,y) scanf("%d%d",&x,&y)
#define scans(x) scanf("%s",x);
#define scanld(x) scanf("%lld",&x)
#define scanldd(x,y) scanf("%lld%lld",&x,&y)
#define rep(i,x,n) for(int i = x;i < n;i++)
#define dep(i,x,n) for(int i = x;i > n;i--)
#define pi 3.141592653589793238462643383249901429

const int maxn = 1e5 + 10;

int k;
struct node{
    int num[5];
    int ans[5];
}Mon[maxn];

bool cmp(node &b,node &a)
{
    for(int i = 0;i < k;i++)
    {
        if(b.num[i] == a.num[i])
            continue;
        return b.num[i] < a.num[i];
    }
    return b.num[0] < a.num[0];
}

struct node2{
    int num[5];
    int ans[5];
    bool operator <(const node2 &a)const{

        for(int i = 1;i < k;i++)
        {
            if( num[i] == a.num[i])
                continue;
            return num[i] > a.num[i];
        }
        return num[1] > a.num[1];
    }
};

struct node3{
    int num[5];
    int ans[5];
    bool operator <(const node3 &a)const{
        for(int i = 2;i < k;i++)
        {
            if( num[i] == a.num[i])
                continue;
            return num[i] > a.num[i];
        }
        return num[2] > a.num[2];
    }
};
struct node4{
    int num[5];
    int ans[5];
    bool operator <(const node4 &a)const{
        for(int i = 3;i < k;i++)
        {
            if( num[i] == a.num[i])
                continue;
            return num[i] > a.num[i];
        }
        return num[3] > a.num[3];
    }
};
struct node5{
    int num[5];
    int ans[5];
    bool operator <(const node5 &a)const{
        for(int i = 4;i < k;i++)
        {
            if( num[i] == a.num[i])
                continue;
            return num[i] > a.num[i];
        }
        return num[4] > a.num[4];
    }
};
priority_queue que2;
priority_queue que3;
priority_queue que4;
priority_queue que5;
int anssum[10];
int tot = 0;
void solve()
{
    if(que2.size())
    {
        while(anssum[1] >= que2.top().num[1])
        {
            node2 temp3 = que2.top();
            que2.pop();
            rep(l,1,k)
            {
                if(anssum[l] >= temp3.num[l])
                {
                    if(l == k - 1)
                    {
                        tot++;
                        rep(j,0,k) anssum[j] +=  temp3.ans[j];
                        solve();
                    }
                    continue;
                }
                else
                {
                    if(l == 2)
                    {
                        node3 temp2;
                        rep(l,0,k) temp2.num[l] =  temp3.num[l],temp2.ans[l] =   temp3.ans[l];
                        que3.push(temp2);
                    }
                    else if(l == 3)
                    {
                        node4 temp2;
                        rep(l,0,k) temp2.num[l] =  temp3.num[l],temp2.ans[l] =   temp3.ans[l];
                        que4.push(temp2);
                    }
                    else if(l == 4)
                    {
                        node5 temp2;
                        rep(l,0,k) temp2.num[l] =  temp3.num[l],temp2.ans[l] =  temp3.ans[l];
                        que5.push(temp2);
                    }
                    break;
                }
            }
            if(que2.empty())
                break;
        }
    }
    if(que3.size())
    {
        while(anssum[2] >= que3.top().num[2])
        {
            node3 temp3 = que3.top();
            que3.pop();
            rep(l,0,k)
            {
                if(anssum[l] >= temp3.num[l])
                {
                    if(l == k - 1)
                    {
                        tot++;
                        rep(jj,0,k) anssum[jj] +=  temp3.ans[jj];
                        solve();
                    }
                    continue;
                }
                else
                {
                    if(l == 3)
                    {
                        node4 temp2;
                        rep(l,0,k) temp2.num[l] =  temp3.num[l],temp2.ans[l] =   temp3.ans[l];
                        que4.push(temp2);
                    }
                    else if(l == 4)
                    {
                        node5 temp2;
                        rep(l,0,k) temp2.num[l] =  temp3.num[l],temp2.ans[l] =  temp3.ans[l];
                        que5.push(temp2);
                    }
                    break;
                }
            }

            if(que3.empty())
                break;
        }
    }
    if(que4.size())
    {
        while(anssum[3] >= que4.top().num[3])
        {
            node4 temp3 = que4.top();
            que4.pop();
            rep(l,0,k)
            {
                if(anssum[l] >= temp3.num[l])
                {
                    if(l == k - 1)
                    {
                        tot++;
                        rep(jj,0,k) anssum[jj] +=  temp3.ans[jj];
                        solve();
                    }
                    continue;
                }
                else
                {
                    node5 temp2;
                    rep(l,0,k) temp2.num[l] =  temp3.num[l],temp2.ans[l] =  temp3.ans[l];
                    que5.push(temp2);
                    break;
                }
            }
            if(que4.empty())
                break;
        }
    }
    if(que5.size())
    {
        while(anssum[4] >= que5.top().num[4])
        {
            node5 temp3 = que5.top();
            que5.pop();
            tot++;
            rep(kk,0,k) anssum[kk] +=  temp3.ans[kk];
            solve();
            if(que5.empty())
                break;
        }                    
    }
}

int main()
{
    int T;
    //scand(T);
    read(T);
    while(T--)
    {
        tot = 0;
        while (!que2.empty())
        {
            que2.pop();
        }
        while(!que3.empty())
            que3.pop();
        while(!que4.empty())
            que4.pop();
        while (!que5.empty())
        {
            que5.pop();
        }
        int n;
        //scandd(n,k);
        read(n);
        read(k);
        rep(i,0,k) read(anssum[i]);
            //scand(anssum[i]);
        rep(i,1,n + 1) {
            for(int j = 0;j < k;j++)
                read(Mon[i].num[j]);//scand(Mon[i].num[j]);
            for(int j = 0;j < k;j++)
                read(Mon[i].ans[j]);//scand(Mon[i].ans[j]);
        }
        sort(Mon + 1,Mon + n + 1,cmp);
        bool flag = false;
        rep(i,1,n+ 1)
        {
            rep(j,0,k)
            {
                if(anssum[j] >= Mon[i].num[j])
                {
                    if(j == k - 1)
                        flag = true;
                    continue;
                }
                else
                {
                    if(j == 1)
                    {
                        node2 temp2;
                        rep(l,0,k) temp2.num[l] = Mon[i].num[l],temp2.ans[l] =  Mon[i].ans[l];
                        que2.push(temp2);
                    }
                    else if(j == 2)
                    {
                        node3 temp2;
                        rep(l,0,k) temp2.num[l] = Mon[i].num[l],temp2.ans[l] =  Mon[i].ans[l];
                        que3.push(temp2);
                    }
                    else if(j == 3)
                    {
                        node4 temp2;
                        rep(l,0,k) temp2.num[l] = Mon[i].num[l],temp2.ans[l] =  Mon[i].ans[l];
                        que4.push(temp2);
                    }
                    else if(j == 4)
                    {
                        node5 temp2;
                        rep(l,0,k) temp2.num[l] = Mon[i].num[l],temp2.ans[l] =  Mon[i].ans[l];
                        que5.push(temp2);
                    }
                    break;
                }
            }
            if(flag)
            {
                rep(jj,0,k) anssum[jj] += Mon[i].ans[jj];
                tot++;
                bool flag2 = false;
                solve();
                flag = false;
            }
        }
        printf("%d\n",tot);
        rep(i,0,k) printf("%d%c",anssum[i]," \n"[i == k - 1]);
    }
}

 

你可能感兴趣的:(2018ACM多校)