一个神奇的随机做法
问题等价于将矩形分成(k)组,使得每组有交
每次(random\_shuffle),把前(k)个强制分(k)组,剩下的依次加入一组,根据交的面积大小比例,选最优的
发现满足条件的就结束
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
mt19937 rnd(49387);
const int N=2e5+4;
int n,k,lx[N],ly[N],rx[N],ry[N],id[N],l1[8],r1[8],l2[8],r2[8];
inline double intersection(int i,int p){
if(rx[p]<l1[i]||lx[p]>r1[i]||ry[p]<l2[i]||ly[p]>r2[i])return 0;
int tl1=max(l1[i],lx[p]),tr1=min(r1[i],rx[p]),tl2=max(l2[i],ly[p]),tr2=min(r2[i],ry[p]);
return (double)(tr1-tl1)*(tr2-tl2)/((long long)(r1[i]-l1[i])*(r2[i]-l2[i]));
}
inline bool solve(){
shuffle(id+1,id+n+1,rnd);
for(int i=1,u;i<=k;i++){
u=id[i];
l1[i]=lx[u];r1[i]=rx[u];
l2[i]=ly[u];r2[i]=ry[u];
}
static double tmp,mx;
for(int i=k+1,u,p;i<=n;i++){
u=id[i];
mx=0;
for(int j=1;j<=k;j++){
tmp=intersection(j,u);
if(tmp>mx){mx=tmp;p=j;}
}
if(mx==0)return 0;
l1[p]=max(l1[p],lx[u]);
r1[p]=min(r1[p],rx[u]);
l2[p]=max(l2[p],ly[u]);
r2[p]=min(r2[p],ry[u]);
}
return 1;
}
int main(){
n=read();k=read();
for(int i=1;i<=n;i++){
lx[i]=read();ly[i]=read();
rx[i]=read();ry[i]=read();
id[i]=i;
}
while(!solve());
for(int i=1;i<=k;i++)
cout<<l1[i]<<" "<<l2[i]<<"
";
return (0-0);
}