POJ
来源:互联网 发布:网上配眼镜靠谱吗 知乎 编辑:程序博客网 时间:2024/06/16 19:59
问题描述
Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i^2 + 100000 × i + j^2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix.
Input
The first line of input is the number of test case.
For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ M ≤ N × N). There is a blank line before each test case.
Output
For each test case output the answer on a single line.
Sample Input
121 12 12 22 32 43 13 23 83 95 15 255 10
Sample Output
3-99993312100007-199987-99993100019200013-399969400031-99939
分析:
这个问题也是典型的查找第k大值,所以依然用二分法,和POJ-3579这题有着异曲同工之处。
分析一下这个式子i^2 + 100000 × i + j^2 - 100000 × j + i × j
我们发现如果定j的话,式子随着i单调递增,那么这样就可以先循环j,内部用二分i来统计小于d的共有多少个数,然后最后判断是否小于M,小于M就是d弄的小了。二分套二分
#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;ll N,M;ll f(ll i, ll j){ return i * i + 100000 * i + j * j - 100000 * j + i * j;}bool C(ll d){ ll cnt = 0; for(int j=1; j<N+1; j++) { ll lb = 0, ub = N+1; while(ub - lb > 1) { ll i = (ub + lb) / 2; if(f(i, j) < d) { lb = i; } else ub = i; } cnt += lb; } return cnt < M;}void solve(){ ll lb = -100000*N, ub = N * N + 100000 * N + N * N + N * N; while(ub - lb > 1) { ll mid = (lb + ub) / 2; if(C(mid)) lb = mid; else ub = mid; } printf("%lld\n", lb);}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d",&N, &M); solve(); } return 0;}
1 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- CWnd直接派生的窗口下使用CToolBar笔记
- Redis之—— Spring4.0 注解Cache+Redis缓存
- linux内核笔记之时间管理(二) : 低精度timer
- linux 内核笔记之时间管理(三) : 高精度timer
- excel 数据处理
- POJ
- linux 内核笔记之watchdog
- sdcc 存储类型关键字
- (每天进步)hibernate的获取
- Vue 模板
- 好记性不如破键盘之百度地图API
- 小型BBS项目--4月26号学习总结
- linux mysql5.7安装
- Java中的Error和Exception