Skip to content

14219: 【原4219】游戏策略

题目

题目描述

author: kstarxin 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4219

题目描述

助教喜欢玩一个MORPG(多人在线角色扮演)游戏,游戏的规则很简单:系统在每轮游戏中随机放出 \( n \) 只怪物, 作为玩家如果能够杀死怪物,就能获得对应的经验奖励。但是助教的操作是在是太菜了,只会被怪物和dalao吊打。
于是助教在完成大作业之余苦练黑客技术,终于黑进了服务器给自己加了特权:助教可以在每一轮游戏正常玩家开始角逐之前先随意选择一些怪物,轻易将其杀死并获得对应的奖励。但是由于助教不想被封号,所以只能选择所有随机放出的怪物中的 \( k \) 只。为了权衡,现在助教希望知道对于不同的 \(k\) ,在游戏中他最多可以获得的经验奖励 \( E \) 是多少。

输入

第一行 \(T,n\) , \(T\) 表示有 \(T\) 次询问。
第二行 \(n\) 个正整数,每个数 \(a_i\) 表示杀死第 \(i\) 只怪物的对应奖励。
接下来 \(T\) 行,每行一个 \(k\) 。

输出

\(T\) 行,每行一个正整数 \(E\),由于结果可能很大,请将每次询问的结果对 \(10^{9} + 7\) 取模。

输入样例

5 5  
1 1 1 1 1  
1  
2  
1  
2  
1

输出样例

1  
2  
1  
2  
1

数据规模

\(0 \le T \le 10^{6},0 \le n \le 2 \times 10^5\)
\(i\) 为正整数,且 \(1 \le i \le n\)
\(k\) 为正整数,且 \(1 \le k \le n, 0 \le a_i \le 10^9 \)

ligongzzz's solution

#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;

const int mod = int(1e9 + 7);
vector<int> value;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T, n;
    cin >> T >> n;

    for (int i = 0; i < n; ++i) {
        int temp;
        cin >> temp;
        value.push_back(temp);
    }

    sort(value.begin(), value.end(), [](int a, int b) {return a > b; });

    for (int i = 1; i < n; ++i)
        value[i] = (value[i - 1] + value[i]) % int(1e9 + 7);

    for (; T > 0; --T) {
        int temp;
        cin >> temp;
        cout << value[temp - 1] << "\n";
    }

    return 0;
}

q4x3's solution

/**
 * 排序
 **/
#include <iostream>
#include <stdio.h>
#define modd 1000000007
using namespace std;

template <typename T>
void merge(int lo, int mi, int hi, T* a)
{
    T* A = a + lo;
    int lb = mi - lo;
    T* B = new T[lb];
    T* BB = B;
    for(int i = 0;i < lb;++ i)
        B[i] = A[i];
    int lc = hi - mi;
    T* C = a + mi;
    int cnt = 0;
    while(1) {
        if ((lb == 0) && (lc == 0)) break;
        if (lb == 0) {
            A[cnt] = C[0];
            ++ cnt; ++ C; -- lc;
        }
        else if (lc == 0) {
            A[cnt] = B[0];
            ++ cnt; ++ B; --lb;
        }
        else {
            if(B[0] < C[0]) {
                A[cnt] = B[0];
                ++ cnt; ++ B; -- lb;
            }
            else {
                A[cnt] = C[0];
                ++ cnt; ++ C; -- lc;
            }
        }
    }
    delete []BB;
}

template <typename T>
void mergeSort(int lo, int hi, T* A)
{
    if(hi - lo < 2) return;
    int mi = (lo + hi) / 2;
    mergeSort(lo, mi, A); mergeSort(mi, hi, A);
    merge(lo, mi, hi, A);
}

int T, n, tmp, a[200233];
long long b[200233];

int main() {
    scanf("%d%d", &T, &n);
    for(register int i = 0;i < n;++ i) {
        scanf("%d", &a[i]);
    }
    mergeSort(0, n, a);
    for(register int i = 1;i <= n;++ i) {
        b[i] = (b[i - 1] + (long long)a[n - i]) % modd;
    }
    for(register int i = 0;i < T;++ i) {
        scanf("%d", &tmp);
        printf("%lld\n", b[tmp]);
    }
}

Zsi-r's solution

#include <iostream>

using namespace std;

int main()
{
    int T, n ,p,q,max=0;
    int tmp;
    cin >> T >> n;

    int *elem = new int[n];
    int *query = new int[T];

    for (int i = 0; i < n;i++)
    {
        cin >> elem[i];
    }

    for (int i = 0; i < T;i++)
    {
        cin >> query[i];
        if(query[i] >max){
            max = query[i];
        }
    }

    for (int N = n; N > 0 ; N--)
    {   
        for (p = n ; p > n-N ; p--)
        {
            q = p - 1;
            if (elem[q] < elem[p])
            {
                tmp = elem[p];
                elem[p] = elem[q];
                elem[q] = tmp;
            }
            if (N == (n+1)-max)
                break;
        }
        if (N == (n+1)-max) break;
    }

    for (int i = 0; i < T;i++)
    {
        int sum=0;
        for (int j = 0; j < query[i];j++)
            sum += elem[j];
        cout << sum <<endl;
    }

    cout << endl;
    cout << max << endl;
    for (int i = 0; i < n;i++)
    {
        cout << elem[i] <<endl;
    }
    return 0;
}