题目:http://codeforces.com/problemset/problem/448/D
题意:给出n,m,k,即在一个n*m的二维数组中找第k大的数,第i行第j列的数的值为i*j。
思路:二分答案,每一行中找比它小的数之和(单调函数),作为check的条件来转移。
#include<bits/stdc++.h> using namespace std; int n,m; long long k; bool check(long long mid) { long long res=0; for(int i=1;i<=n;i++) { res+=min(mid/i,1ll*m); } if(res>=k)return 1; return 0; } int main() { scanf("%d%d%lld",&n,&m,&k); long long l=1,r=1ll*n*m,ans=-1; while(l<=r) { long long mid=l+r>>1; if(check(mid)) { ans=mid; r=mid-1; } else l=mid+1; } printf("%lld\n",ans); return 0; }