2018 Multi-University Training Contest 7 1011 Swordsman

 

题意:英雄有k种属性,现在面对n个怪兽,每个怪兽也有k个属性与英雄对应,如果英雄的每项属性都不低于某个怪兽,那么他就可以杀死它并且一一加上怪兽的所有属性,求英雄最多可以杀死几只怪兽并输出怪兽编号

 

一个怪兽只能被杀一次,说明只需要遍历一次这个怪兽的所有属性即可,可以对每种属性记录所属怪兽编号并单独排序,这样可以得到k组数据,每组数据的属性种类都相同且升序,那么每一轮只要依次遍历k组数,每组遍历到大于英雄属性值停止,并标记属性比英雄小的怪兽的编号,只要某个怪兽被标记k次,就杀死那个怪兽并增加属性值,依次循环直到全部杀死或者某一轮不再有怪兽被标记k次。

题目要求fread,不加就TLE

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define ll long long
const int maxm = 100005;
const int BUF = 40000000;
char Buf[BUF], *buf = Buf;
const int OUT = 20000000;
char Out[OUT], *ou = Out;int Outn[30], Outcnt;
inline void write(int x) 
{
    if (!x)*ou++ = 48;
    else 
    {
        for (Outcnt = 0;x;x /= 10)Outn[++Outcnt] = x % 10 + 48;
        while (Outcnt)*ou++ = Outn[Outcnt--];
    }
}
inline void writell(ll x)
{
    if (!x)*ou++ = 48;
    else {
        for (Outcnt = 0;x;x /= 10)Outn[++Outcnt] = x % 10 + 48;
        while (Outcnt)*ou++ = Outn[Outcnt--];
    }
}
inline void writechar(char x) { *ou++ = x; }
inline void writeln() { *ou++ = '\n'; }
inline void read(int&a) { for (a = 0;*buf<48;buf++);while (*buf>47)a = a * 10 + *buf++ - 48; }
struct node
{
    int val, id;
    bool operator<(const node &r)const
    {
        return val < r.val;
    }
}f[6][maxm], b[maxm][6];
int a[6], L[6], rr[7], s[maxm], flag[maxm][6];
int main()
{
    fread(Buf, 1, BUF, stdin);
    int n, i, j, k, sum, t, m, ans;
    read(t);
    while (t--)
    {
        read(n), read(m);
        ans = 0;
        for (i = 1;i <= m;i++)
            read(a[i]), L[i] = 0;
        for (i = 1;i <= n;i++) s[i] = 0;
        for (i = 1;i <= n;i++)
        {
            for (j = 1;j <= m;j++)
            {
                read(f[j][i].val);
                f[j][i].id = i;
            }
            for (j = 1;j <= m;j++)
                read(b[i][j].val);
        }
        for (i = 1;i <= m;i++)
            sort(f[i] + 1, f[i] + 1 + n);
        int tmp;
        while (1)
        {
            tmp = 0;
            for (i = 1;i <= m;i++)
            {
                for (j = L[i] + 1;j <= n;j++)
                {
                    if (a[i] >= f[i][j].val)
                    {
                        int x = f[i][j].id;
                        s[x]++;
                        if (s[x] == m)
                        {
                            for (k = 1;k <= m;k++)
                                a[k] += b[x][k].val;
                            ans++, tmp = 1;
                        }
                        L[i] = j;
                    }
                    else break;
                }
            }
            if (!tmp || ans == n) break;
        }
        printf("%d\n", ans);
        for (i = 1;i < m;i++)
            printf("%d ", a[i]);
        printf("%d\n", a[i]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值