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

刚刚越过绝境长城,只见天空中出现了炫目的光芒 —— 圣诞老人出现了。

元旦三侠立刻进入战斗。生蛋侠、圆蛋侠和零蛋侠分别有 na,nb,ncna,nb,nc 个激光炮。生蛋侠的激光炮的威力分别为 a0,a1,…,ana−1a0,a1,…,ana−,圆蛋侠的激光炮的威力分别为 b0,b1,…,bnb−1b0,b1,…,bnb−,零蛋侠的激光炮的威力分别为 c0,c1,…,cnc−1c0,c1,…,cnc−。

元旦三侠的激光炮的威力已经按从小到大的顺序排好序了,即 ai−≤aiai−≤ai,bi−≤bibi−≤bi,ci−≤cici−≤ci。

由于元旦三侠精力有限,他们得废弃掉 kk 个激光炮。为了更好地进行战斗,他们决定废弃掉威力前 kk 小的激光炮。

赶快帮助元旦三侠,让激光炮投入战斗吧!你只需要告诉他们威力第 kk 小的激光炮威力是多少。

任务
你需要编写一个函数 query_kth,以确定威力值第 kk 小的激光炮威力值是多少。 query_kth(n_a, n_b, n_c, k)
n_a:生蛋侠拥有的激光炮数目 nana。保证 na≥0na≥。
n_b:圆蛋侠拥有的激光炮数目 nbnb。保证 nb≥0nb≥。
n_c:零蛋侠拥有的激光炮数目 ncnc。保证 nc≥0nc≥。
kk:要查询的排名 kk。保证 ≤k≤na+nb+nc1≤k≤na+nb+nc。
你可以调用三个函数 get_a、get_b、get_c 以帮助你确定第 kk 小的激光炮。我们会根据你调用这三个函数的总次数评分。 get_a(i) 将返回 aiai。如果 ii 在 ≤i<na0≤i<na 之外,该函数将返回 。
get_b(i) 将返回 bibi。如果 ii 在 ≤i<nb0≤i<nb 之外,该函数将返回 。
get_c(i) 将返回 cici。如果 ii 在 ≤i<nc0≤i<nc 之外,该函数将返回 。
在一组测试数据中,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;
如果有不清楚的地方,见样例及测评库下载,内附了样例程序。 评测方式
评测系统将读入如下格式的输入数据: 第 行: na,nb,nc,kna,nb,nc,k
第 行:nana 个整数,第 ii 个整数表示 aiai。
第 行:nbnb 个整数,第 ii 个整数表示 bibi。
第 行:ncnc 个整数,第 ii 个整数表示 cici。
在 query_k 返回后,评测系统将输出你的答案以及 get_a, get_b, get_c 三个函数的总调用次数。 样例一
input output explanation 所有激光炮从小到大排序后为 ,,,,,,,,,,,,,,,所以第 小的数为 。输出的第二个整数 为总调用次数,你可以认为这是一个调用了 次 get_a, get_b, get_c 函数的程序的输出。 样例二
见样例及测评库下载。 限制与约定
共 个测试点,每个测试点 分。设你的程序 get_a, get_b, get_c 函数的调用次数为 tt。当 t≤100t≤ 时得 分,否则当 t≤2000t≤ 时得 分,否则不得分。 测试点编号 特殊限制
na,nb,nc≤30na,nb,nc≤
nc=0nc= 无 对于所有测试点,≤na,nb,nc≤≤na,nb,nc≤,≤ai,bi,ci≤≤ai,bi,ci≤。 交互式类型的题目怎么本地测试 时间限制: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=,cb=,cc=;
int ta,tb,tc;
int minn,t;
while(k)
{
int t=max(,k/-);
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;
}

代码

05-11 16:58