• 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]<<"
    ";
    	return (0-0);
    }
    
  • 相关阅读:
    【模板】高斯消元
    【洛谷P1730】最小密度路径
    【模板】矩阵乘法优化线性递推
    【洛谷P3723】礼物
    【洛谷P3338】力
    【模板】NTT
    【洛谷P1919】A*B Problem升级版
    测试理论基础(思维导图)
    Fiddler
    常用 Linux 命令
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12552287.html
Copyright © 2020-2023  润新知