链接: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 5 无 6 7 8 9 10 对于所有测试点,0≤na,nb,nc≤1050≤na,nb,nc≤105,1≤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; }