题意:
给你 n ∗ m n*m n∗m的矩阵点阵(有 n ∗ m n*m n∗m个点),让你找与原点围成面积的第k大值
思路:
二分:
二分我们想要的第k大值,如果这个面积不够大,也就是能围成这个面积的点少于k个,那么扩大这个面积,让l=mid+1,否则,就缩小面积,让r=mid,check函数就扫一遍每一行,看每一行有多少点满足就好了,复杂度为: n l o g ( n m ) nlog(nm) nlog(nm)
代码:
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define f(i,a,n) for(int i=a;i<n;++i)
#define ff(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
typedef double dbl;
typedef pair<int, int> pi;
const int INF = 0x3f3f3f3f;
ll n,m,k;
//找比它小或等于的点有多少个
ll check(ll x){
ll ans=0;
for(int i=1;i<=n;i++){
ans+=min(m,x/i);
}
return ans;
}
int main(){
// freopen("D:\\Users\\HP ZBook15\\CLionProjects\\untitled\\demo\\in.TXT","r",stdin);
// freopen("D:\\Users\\HP ZBook15\\CLionProjects\\untitled\\demo\\out.TXT","w",stdout);
cin>>n>>m>>k;
ll l=0,r=n*m;
while(l<r){
int mid=(l+r)>>1;
if(check(mid)>=(m*n-k))r=mid;
else l=mid+1;
}
cout<<l<<endl;
return 0;
}
然后发现会TLE,于是改了一行代码,把int mid=(l+r)>>1;
改为了ll mid=(l+r)>>1;
就变成了WA,之后把if(check(mid)>=(m*n-k))r=mid;
改为了if(check(mid)>=(m*n-k+1))r=mid;
就AC了,因为有
(
m
∗
n
−
k
+
1
)
(m*n-k+1)
(m∗n−k+1)个点面积比k小或等于,那第一个比它大的就只能排到第
(
m
∗
n
−
k
)
(m*n-k)
(m∗n−k)位了,它也就是恰好第k大的了
堆:
设置一个pair类型的堆,开始插入从1×m到n×m的元素(值与左下标)进入堆中,然后通过把堆顶元素减去一个下标再放入堆中,知道循环k次即可
代码:
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define f(i,a,n) for(int i=a;i<n;++i)
#define ff(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
typedef double dbl;
typedef pair<int, int> pi;
const int INF = 0x3f3f3f3f;
struct node{
ll x, y;
bool operator < (const node& rhs) const{
if(x * y == rhs.x * rhs.y) return x < rhs.x;
return x * y < rhs.x * rhs.y;
}
};
int main(){
// freopen("D:\\Users\\HP ZBook15\\CLionProjects\\untitled\\demo\\in.TXT","r",stdin);
// freopen("D:\\Users\\HP ZBook15\\CLionProjects\\untitled\\demo\\out.TXT","w",stdout);
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
priority_queue<node> q;
q.push(node{n, m});
set<node> s;
while(1){
node u = q.top(); q.pop();
if(--k == 0){
printf("%lld\n", u.x * u.y);
break;
}
if(s.find(node{u.x - 1, u.y}) == s.end()){
q.push(node{u.x - 1, u.y});
s.insert(node{u.x - 1, u.y});
}
if(s.find(node{u.x, u.y - 1}) == s.end()){
q.push(node{u.x, u.y - 1});
s.insert(node{u.x, u.y - 1});
}
}
return 0;
}