首页 > 其他分享 >[AHOI2014/JSOI2014]拼图

[AHOI2014/JSOI2014]拼图

时间:2022-12-14 21:02:17浏览次数:51  
标签:JSOI2014 拼图 AHOI2014 long int lst 矩形 sum 300001

链接:https://www.luogu.com.cn/problem/P4039 题目描述:有一些长为$n$,宽为$w_{i}$的黑白色矩形,要将它们拼成一个$n\times m$的大矩形,求大矩形中最大的全白子矩形的面积的最大值。 题解:话说我一开始只会$O(n^2m)$,不会$O(m^2n)$,尽管知道这题可以根号分治都不会做。 $n\times m<=10^5$,这让人莫名想起CmdOI2019简单的数论题。依照那题的方法,我们可以考虑根号分治,考虑$O(n^2m)$与$O(m^2n)$两种情况。 $O(n^2m)$:可以暴力枚举行的左右端点,对于这$S$个矩形,我们可将完整的白块放在中间,两边各放两个靠右边$0$列最多的块与靠左边$0$列最多的块,这样拼是最优的。 $O(nm^2)$:记每一个点$(i,j)$离他最近的$1$的行为$up_{i,j}$,将枚举行的左右端点时换作枚举每个点,判时判左端点为$up_{i,j}+1$,右端点为$i$的情况即可。 当然,这题有个小坑:每个矩形本身的最大的全白子矩形也要统计到达答案里。 ``` #include #include #include #define inf 1e9 using namespace std; int n,m,S,w[300001],lst[300001]; int p[300001],up[300001],sum[300001],T[300001],length; long long ans; char t; int f(int l,int r) { if (l==0||r==0) return 0; return (l-1)*m+r; } int getsum(int l,int r,int l2,int r2) { return sum[f(r,r2)]-sum[f(l-1,r2)]-sum[f(r,l2-1)]+sum[f(l-1,l2-1)]; } void solve(int l,int r) { long long res=0,ll,rr,maxr=0,maxn=0,maxr2=0,maxn2=0,mixn=0,mixn2=0; for (int i=1;i<=S;++i) { if (getsum(l,r,lst[i-1]+1,lst[i])==0) res+=w[i]; else { for (int j=lst[i-1]+1;j<=lst[i];++j) if (getsum(l,r,lst[i-1]+1,j)!=0) { if (j-lst[i-1]-1>maxn) { maxn=j-lst[i-1]-1; maxr=i; } else if (j-lst[i-1]-1>mixn) mixn=j-lst[i-1]-1; break; } for (int j=lst[i];j>=lst[i-1]+1;--j) if (getsum(l,r,j,lst[i])!=0) { if (lst[i]-j>maxn2) { maxn2=lst[i]-j; maxr2=i; } else if (lst[i]-j>mixn2) mixn2=lst[i]-j; break; } ll=lst[i-1]+1; rr=-inf; for (int j=lst[i-1]+1;j<=lst[i];++j) { if (getsum(l,r,j,j)==0) rr=j; else { ans=max(ans,(r-l+1)*(rr-ll+1)); ll=j+1; } } } } if (maxr==maxr2) ans=max(ans,(res+max(mixn2+maxn,mixn+maxn2))*(r-l+1)); else ans=max(ans,(res+maxn+maxn2)*(r-l+1)); return; } void work() { ans=length=m=0; scanf("%d%d",&S,&n); for (int i=1;i<=S;++i) { scanf("%lld",&w[i]); m+=w[i]; lst[i]=lst[i-1]+w[i]; for (int k=1;k<=n*w[i];++k) { ++length; T[length]=0; while (T[length]!='0'&&T[length]!='1') T[length]=getchar(); } } length=0; for (int i=1;i<=S;++i) for (int k=1;k<=n;++k) for (int j=lst[i-1]+1;j<=lst[i];++j) { ++length; p[f(k,j)]=T[length]-'0'; } int pointer; for (int i=1;i<=m;++i) { pointer=0; for (int j=1;j<=n;++j) { if (p[f(j,i)]==1) pointer=j; up[f(j,i)]=pointer; } } for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) sum[f(i,j)]=p[f(i,j)]+sum[f(i-1,j)]+sum[f(i,j-1)]-sum[f(i-1,j-1)]; if (n

标签:JSOI2014,拼图,AHOI2014,long,int,lst,矩形,sum,300001
From: https://www.cnblogs.com/zhouhuanyi/p/16983522.html

相关文章

  • [JSOI2014]支线剧情2
    链接:https://vjudge.net/problem/HYSBZ-5031题目描述:给定一个树形图,规定一号点为根节点。到达一个点时可以进行下列操作:$1$.沿着一条有向边走到下一个节点。$2$.回到......
  • [AHOI2014/JSOI2014]骑士游戏
    链接:https://www.luogu.com.cn/problem/P4042题目描述:对于一个怪物$i$,可以花费$c_{i}$的代价将其变为一个怪物集合,或花费$c2_{i}$的代价消灭他。求消灭怪物$1$的最小代......
  • java 简单拼图小游戏的实现
    这个是游戏页面的源代码packagePuzzle;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.KeyEvent;importjava.awt.event......
  • JAVA-动漫美女拼图—完结篇(重置业务实现)
    代码一packagecom.itheima_10;publicclassApp{publicstaticvoidmain(String[]args){PictureFramepf=newPictureFrame();}}代码二pa......
  • JAVA-动漫拼图图片移动业务遗留问题处理
    packagecom.itheima_09;publicclassApp{publicstaticvoidmain(String[]args){PictureFramepf=newPictureFrame();}}packagecom.ithe......
  • JAVA_动漫拼图求助业务实现
    packagecom.itheima_08;publicclassApp{publicstaticvoidmain(String[]args){PictureFramepf=newPictureFrame();}}packagecom.ithe......
  • JAVA- 动漫美女拼图(给按钮添加事件)
    代码一packagecom.itheima_05;publicclassApp{publicstaticvoidmain(String[]args){PictureFramepf=newPictureFrame();}}代码二pa......
  • JAVA- 动漫美女拼图(记录0号图片位置)
    代码一packagecom.itheima_02;publicclassApp{publicstaticvoidmain(String[]args){PictureFramepf=newPictureFrame();}}代码二pa......
  • JAVA-动漫美女拼图游戏
    代码1packagecom.itheima_02;publicclassApp{publicstaticvoidmain(String[]args){PictureFramepf=newPictureFrame();}}代码2p......
  • 学习记录23java拼图小游戏
    拼图目标GUI(GraphicalUserInterface,图形用户接口)这是指采用图形化的方式显示操作界面,几乎所有的语言都有GUI的知识java中有两套完整的体系:AWT包(出现的比较早,可能......