• #52. 【UR #4】元旦激光炮 (交互式题)


    链接:http://uoj.ac/problem/52

    刚刚越过绝境长城,只见天空中出现了炫目的光芒 —— 圣诞老人出现了。
    
    元旦三侠立刻进入战斗。生蛋侠、圆蛋侠和零蛋侠分别有 na,nb,ncna,nb,nc 个激光炮。生蛋侠的激光炮的威力分别为 a0,a1,…,ana−1a0,a1,…,ana−1,圆蛋侠的激光炮的威力分别为 b0,b1,…,bnb−1b0,b1,…,bnb−1,零蛋侠的激光炮的威力分别为 c0,c1,…,cnc−1c0,c1,…,cnc−1。
    
    元旦三侠的激光炮的威力已经按从小到大的顺序排好序了,即 ai−1≤aiai−1≤ai,bi−1≤bibi−1≤bi,ci−1≤cici−1≤ci。
    
    由于元旦三侠精力有限,他们得废弃掉 kk 个激光炮。为了更好地进行战斗,他们决定废弃掉威力前 kk 小的激光炮。
    
    赶快帮助元旦三侠,让激光炮投入战斗吧!你只需要告诉他们威力第 kk 小的激光炮威力是多少。
    
    任务
    你需要编写一个函数 query_kth,以确定威力值第 kk 小的激光炮威力值是多少。
    
    query_kth(n_a, n_b, n_c, k)
    n_a:生蛋侠拥有的激光炮数目 nana。保证 na≥0na≥0。
    n_b:圆蛋侠拥有的激光炮数目 nbnb。保证 nb≥0nb≥0。
    n_c:零蛋侠拥有的激光炮数目 ncnc。保证 nc≥0nc≥0。
    kk:要查询的排名 kk。保证 1≤k≤na+nb+nc1≤k≤na+nb+nc。
    你可以调用三个函数 get_a、get_b、get_c 以帮助你确定第 kk 小的激光炮。我们会根据你调用这三个函数的总次数评分。
    
    get_a(i) 将返回 aiai。如果 ii 在 0≤i<na0≤i<na 之外,该函数将返回 21474836472147483647。
    get_b(i) 将返回 bibi。如果 ii 在 0≤i<nb0≤i<nb 之外,该函数将返回 21474836472147483647。
    get_c(i) 将返回 cici。如果 ii 在 0≤i<nc0≤i<nc 之外,该函数将返回 21474836472147483647。
    在一组测试数据中,query_kth 只会被调用一次。
    
    实现细节
    本题只支持 C/C++/Pascal。
    
    你只能提交一个源文件实现如上所述的 query_kth 函数,并且遵循下面的命名和接口。
    
    C/C++
    
    你需要包含头文件 kth.h。
    
    int query_kth(int n_a, int n_b, int n_c, int k);
    函数 get_a, get_b, get_c 的接口信息如下。
    
    int get_a(int p);
    int get_b(int p);
    int get_c(int p);
    Pascal
    
    你需要使用单元 graderhelperlib。
    
    function query_kth(n_a, n_b, n_c, k : longint) : longint;
    函数 get_a, get_b, get_c 的接口信息如下。
    
    function get_a(p : longint) : longint;
    function get_b(p : longint) : longint;
    function get_c(p : longint) : longint;
    如果有不清楚的地方,见样例及测评库下载,内附了样例程序。
    
    评测方式
    评测系统将读入如下格式的输入数据:
    
    第 11 行: na,nb,nc,kna,nb,nc,k
    第 22 行:nana 个整数,第 ii 个整数表示 aiai。
    第 33 行:nbnb 个整数,第 ii 个整数表示 bibi。
    第 44 行:ncnc 个整数,第 ii 个整数表示 cici。
    在 query_k 返回后,评测系统将输出你的答案以及 get_a, get_b, get_c 三个函数的总调用次数。
    
    样例一
    input
    
    2 3 3 5
    1 2
    1 5 6
    2 3 3
    
    output
    
    3 6
    
    explanation
    
    所有激光炮从小到大排序后为 1,1,2,2,3,3,5,61,1,2,2,3,3,5,6,所以第 55 小的数为 33。输出的第二个整数 66 为总调用次数,你可以认为这是一个调用了 66 次 get_a, get_b, get_c 函数的程序的输出。
    
    样例二
    见样例及测评库下载。
    
    限制与约定
    共 1010 个测试点,每个测试点 1010 分。设你的程序 get_a, get_b, get_c 函数的调用次数为 tt。当 t≤100t≤100 时得 1010 分,否则当 t≤2000t≤2000 时得 66 分,否则不得分。
    
    测试点编号    特殊限制
    1    na,nb,nc≤30na,nb,nc≤30
    2    nc=0nc=0
    3
    4
    56
    7
    8
    9
    10
    对于所有测试点,0≤na,nb,nc≤1050≤na,nb,nc≤1051≤ai,bi,ci≤1091≤ai,bi,ci≤109。
    
    交互式类型的题目怎么本地测试
    
    时间限制:1s1s
    空间限制:256MB
    题干

    第一次接触交互式的题目,挺费事的,但还挺有趣的。

    思路:

      如果你一个一个读取就超时了,但如果我读每组数的第k/3个,可以保证的是最小的那一列肯定在所有数的前K小。这句话是关键。

      然后k就减小k/3,重复以上操作,直到k为零。

      注意一下细节问题就行啦。

    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include"kth.h"
    using namespace std;
    int query_kth(int n_a,int n_b,int n_c,int k)
    {
        int ca=0,cb=0,cc=0;
        int ta,tb,tc;
        int minn,t;
        while(k)
        {
            int t=max(0,k/3-1);
            ta=get_a(ca+t),tb=get_b(cb+t),tc=get_c(cc+t);
            minn=min(ta,min(tb,tc));t++;
            if(minn==ta) ca+=t;else if(minn==tb)    cb+=t;else cc+=t;
            k-=t;    
        }
        return minn;
    }
    代码
  • 相关阅读:
    满屏的宽高纯CSS布局
    截屏上传插件开发流程
    COM ACTIVEX 中的BSTR 类型与其它类型转换
    线程中访问控件
    OOP三言两语
    通过iframe上传
    历年作品点评
    每周进度及工作量统计2016090820160915
    英文词频统计的java实现方法
    四人小组项目——连连看
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7395220.html
Copyright © 2020-2023  润新知