P7181题解
KohaD_SEGA · · 题解
这个题是波罗的海
我们来看看
这意味着我们只需考虑矩形的左上顶点和右下顶点,将原点与此二顶点相连的射线与边界交于两点,这两点之间的边界点中的整点即为我们所求的
则题目变成:给定
#include <bits/stdc++.h>
using namespace std;
struct el // 区间
{
int h;//区间的整点边界
int tp;//是区间左界还是右界
}m[20001];//区间有两个界,所以是10000*2
struct ju//矩形
{
int x_1;
int y_1;
int x_2;
int y_2;
}mas[10001];
int len,pried;
int maxx,maxy,n;
inline bool cmp(el A,el B)//排序
{
if(A.h==B.h) return A.tp>B.tp;
else return A.h<B.h;
}
#define QKSORT(l,r) sort(m+(l),m+(r),cmp)
inline void add(int x,int y,int tp)
{
double a;
m[++len].tp=tp;
if(x*1LL*maxy<=y*1LL*maxx) m[len].h=maxy;//只考虑外边界矩形的某一边
else
{
a=(long long)maxx*1LL*y;
a=a*1.0/x;
if(tp>0) m[len].h=ceil(a-0.0001);//防止奇怪的浮点数出错
else m[len].h=floor(a+0.0001);
}
}
int sum(int* x,int* y)
{
int k,mx,mxh;
len=0;
for(int i=1;i<=n;i++)
{
if((long long)1LL*mas[i].x_1*maxy<1LL*mas[i].y_1*maxx) continue;//它属于另外一边
add(mas[i].x_1,mas[i].y_1,1);
add(mas[i].x_2,mas[i].y_2,-1);
}
if(len>0) QKSORT(1,len);
k=0,mx=0,mxh=0;
for(int i=1;i<=len;i++)
{
k+=m[i].tp;
if(k>mx) mx=k,mxh=m[i].h;
}
*x=maxx,*y=mxh;
return mx;
}
int main()
{
ios::sync_with_stdio(false);
cin>>maxx>>maxy>>n;
int tmp=0,i=1;
for(int j=1;j<=n;j++)
{
cin>>mas[i].x_1>>mas[i].y_1>>mas[i].x_2>>mas[i].y_2;
if(mas[i].x_1==0 && mas[i].y_1==0)
pried++;
else
{
swap(mas[i].x_1,mas[i].x_2);
i++,tmp++;
}
}
n=tmp;
int ats,ax=0,ay=0,bx=0,by=0;
ats=sum(&ax,&ay);
swap(maxx,maxy);//全部取反,考虑另一边
for(int i=1;i<=n;i++)
{
swap(mas[i].x_1,mas[i].y_1);
swap(mas[i].x_2,mas[i].y_2);
swap(mas[i].x_1,mas[i].x_2);
swap(mas[i].y_1,mas[i].y_2);
}
tmp=sum(&by,&bx);
if(ats<tmp) ats=tmp,ax=bx,ay=by;//合并两边,得到答案
cout<<ats+pried<<' '<<ax<<' '<<ay<<endl;
return 0;
}