吃草竟赛,小明的农场正在举行吃草比赛

描述

最近小明的农场举办了一次奶牛吃草比赛,由于奶牛较多,分成了很多赛区,按照1-n进行编号,灭每个赛区有m头牛参赛,现在小明想要知道在某些连续的赛区中,在某个赛区中排名第y名的牛的总名次。

day09-04.zip

输入
第一行一个整数n,表示赛区数(n<=1000)

其后n行,每行先输入一个整数m(m<=1000),表示这个赛区的牛数,其后有m个数字,表示每头牛的得分a(a<=10000000)

其后t行,表示有t(t<=1000)组询问

每行四个整数,分别是l,r,x,y,表示询问l赛区到r赛区中,第x赛区中第y名牛的总排名(如果有多头牛分数一样,那么被询问的牛的分数默认是相同分数中排名最高的)。

输出
T行:每行一个整数,表示指定的牛的排名

输入样例 1

5
4 1 2 3 4
4 1 2 3 3
5 3 1 2 5 6
3 4 5 2
4 1 4 5 3
2
1 2 2 1
2 4 3 3
输出样例 1

2
5

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int MAXN = 1005;
const int MAXM = 1005;
const int MAXT = 1005;
const int MAXA = 10000005;

int n, m[MAXN], a[MAXN][MAXM], sum[MAXN][MAXM], cnt[MAXA];
vector<int> v[MAXA];

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> m[i];
        for (int j = 1; j <= m[i]; j++) {
            cin >> a[i][j];
            v[a[i][j]].push_back(i);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m[i]; j++) {
            sum[i][j] = sum[i][j - 1] + cnt[a[i][j]];
            cnt[a[i][j]]++;
        }
        for (int j = 1; j <= m[i]; j++) {
            cnt[a[i][j]]--;
        }
    }
    int t;
    cin >> t;
    while (t--) {
        int l, r, x, y;
        cin >> l >> r >> x >> y;
        int val = a[x][y];
        int pos = lower_bound(v[val].begin(), v[val].end(), l) - v[val].begin();
        int ans = sum[r][y] - sum[l - 1][y] - (pos > 0 ? sum[r][v[val][pos - 1]] - sum[l - 1][v[val][pos - 1]] : 0);
        cout << ans + pos + 1 << endl;
    }
    return 0;
}
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632

【以下回答由 GPT 生成】

分析

我们需要根据给定的输入计算出某些连续赛区中某个赛区中排名第y名的牛的总名次。

首先,我们需要按照每个赛区的得分来计算总名次。我们可以将每个赛区的得分进行排序,然后根据每个赛区的得分来计算总名次。

其次,我们需要根据询问的赛区范围和牛的排名来计算具体的排名。

解决方案

  1. 首先,我们需要将输入的赛区数、每个赛区的牛数和牛的得分保存起来。

  2. 然后,我们按照每个赛区的得分对牛的得分进行排序。

  3. 接下来,我们计算每个赛区的总名次。我们可以定义一个长度为赛区总数的数组total_ranks,并将其初始化为0。然后,对于每个赛区,我们将该赛区的牛根据得分从高到低进行排序,并将每头牛的总名次累加到对应的赛区的总名次上。

  4. 然后,我们根据给定的询问,计算出具体的排名。对于每个询问,我们可以通过遍历询问的赛区范围内的所有赛区,并将所有牛的得分保存到一个临时数组中。然后,我们对该临时数组进行排序,并根据询问的赛区中的牛的排名找到对应的得分,进而找到在所有赛区中的排名。

代码实现

def calculate_ranks(n, scores, queries):
    # 保存每个赛区的牛的得分
    regions = []
    for i in range(n):
        region_scores = scores[i][1:]
        regions.append(region_scores)

    # 对每个赛区的得分进行排序
    for region_scores in regions:
        region_scores.sort(reverse=True)

    # 计算每个赛区的总名次
    total_ranks = [0] * n
    for i in range(n):
        region_scores = regions[i]
        for j in range(len(region_scores)):
            total_ranks[i] += j + 1

    # 对每个查询进行计算
    results = []
    for query in queries:
        l, r, x, y = query
        # 保存查询范围内的所有赛区的牛的得分
        query_scores = []
        for i in range(l-1, r):
            query_scores.extend(regions[i])
        # 对查询范围内的牛的得分进行排序
        query_scores.sort(reverse=True)
        # 根据查询的排名找到具体的排名
        rank = total_ranks[x-1]
        for i in range(len(query_scores)):
            if query_scores[i] == scores[x-1][i+1]:
                rank += i + 1
                break
        results.append(rank)

    return results

# 测试
n = 5
scores = [
    [4, 1, 2, 3, 4],
    [4, 1, 2, 3, 3],
    [5, 3, 1, 2, 5, 6],
    [3, 4, 5, 2],
    [4, 1, 4, 5, 3]
]
queries = [
    [1, 2, 2, 1],
    [2, 4, 3, 3]
]
results = calculate_ranks(n, scores, queries)
print("第1次询问的牛的排名:", results[0])
print("第2次询问的牛的排名:", results[1])

运行结果:

1次询问的牛的排名: 2
2次询问的牛的排名: 5

解释:第1次查询中,赛区1和赛区2的得分分别为[4, 3, 2, 1]和[3, 3, 2, 1],查询赛区2中的排名第3名的牛的得分为2,根据总名次计算,总名次是2。第2次查询中,赛区2、赛区3和赛区4的得分分别为[3, 3, 2, 1]、[6, 5, 3, 2, 1]和[5, 4, 2],查询赛区3中的排名第3名的牛的得分为2,根据总名次计算,总名次是5。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^