JOISC2020DAY1汉堡肉


一个神奇的随机做法

问题等价于将矩形分成\(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]<<"\n";
	return (0-0);
}
posted @ 2020-03-23 15:07  starusc  阅读(414)  评论(0)    收藏  举报