重庆邮电大学第十一届ACM程序设计竞赛-网络选拔赛 C题
阅读原文时间:2023年07月08日阅读:1

时间限制: 1.000 sec 内存限制: 128 MB

武林要以和为贵,张麻子不讲武德来偷袭马老师的亲传弟子。
马老师有n个亲传弟子,每个弟子有一个武力值a[i]。
n个弟子中只有某些弟子学会了闪电鞭,张麻子想知道如果自己的武力值为W可以打败多少个会闪电鞭的亲传弟子(只有W严格大于a[i],才可以打败第i个弟子)。

输入

第一行一个整数T(1<=T<=100),表示数据组数
每组数据第一行两个整数n(1<=n<=100000),m(1<=m<=100000),分别表示亲传弟子数量,询问的数量
接下来一行n个整数,第i个整数a[i]表示第i个弟子的武力值(0<=a[i]<=100000)
接下来一行n个整数,第i个整数b[i]为1或0,b[i]为1表示第i个弟子会闪电鞭,为0则不会闪电鞭.
接下来m行,每行一个整数W(0<=W<=100000)表示张麻子武力值
保证所有T组数据的n加起来不超过100000,m加起来不超过100000

输出

输出T组数据
每组数据输出m行,每行一个整数,表示张麻子武力值为W时,能打败的会闪电鞭的弟子数量

样例输入

1
5 3
1 2 3 2 1
1 0 1 1 0
0
1
6

样例输出

0
0
3

这道题卡时间卡的比较厉害,其他都还好

题解用的文件输入,在本地调试需要用一个a.txt来输入

#include <stdio.h>
#include <stdlib.h>

#define DEBUG 0    //提交的时候需要把DEBUG设为0

#if DEBUG
#else
#define fp stdin
#endif

int fight[100000];
int* follow; //总共100000个元素 下标即为战斗力

int main() {
#if DEBUG
    FILE* fp;
#endif
    int t;
    int i, j;
    int n, m;
    int master;
    int w;
    int cnt;
    int total;  //会闪电鞭的弟子总数
    int max, min;
#if DEBUG
    fp = fopen("a.txt", "r");
#endif
    while (fscanf(fp, "%d", &t) != EOF) {   //读入t
        break;
    }

    while (t--) {
        max = -1;
        min = 100001;
        while (fscanf(fp, "%d%d", &n, &m) != EOF) { //读入每组开头的n和m
            break;
        }
        for (i = 0; i < n; i++) {
            while (fscanf(fp, "%d", &fight[i]) != EOF) {    //将每名弟子的战斗力存入数组
                break;
            }
            if (max < fight[i]) {   //找最大值
                max = fight[i];
            }
            if (min > fight[i]) {   //找最小值
                min = fight[i];
            }
        }
        total = 0;  //每次判断前初始化total为0
        follow = (int*)calloc(sizeof(int), 100001); //使用calloc在堆中为follow开辟空间并初始化为0
        for (i = 0; i < n; i++) {
            while (fscanf(fp, "%d", &master) != EOF) {
                break;
            }
            if (master == 1) {
                follow[fight[i]]++; //follow的下标即为战斗力, follow元素存的是总人数, 例如follow[2] = 3, 战斗力为2的弟子总共有3人
                total++;    //计算会闪电鞭的弟子的总人数
            }
        }
        i = m;
        while (i--) {
            while (fscanf(fp, "%d", &w) != EOF) {
                break;
            }
            if (w <= min) {     //张麻子比最弱的还弱, 输出0
                printf("0\n");
                continue;
            }
            else if (w > max) { //张麻子比最强的还要强, 输出弟子总数
                printf("%d\n", total);
                continue;
            }
            //张麻子战斗力在中间则从w-1开始, 往后求和, 到min结束
            cnt = 0;
            for (j = w - 1; j >= min; j--) {
                cnt += follow[j];
            }
            printf("%d\n", cnt);
        }
        free(follow);   //回收follow的内存空间以便再次申请
    }

    return 0;
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章