BZOJ4614 UVA1742 Oil 计算几何+搜索(未完成

正解:计算几何+搜索+某神仙处理方法(并不知道用的方法叫什么只知道很妙啊QAQ之前猫爷港的时候说扫描线balabala的是扫描线嘛qwq

解题报告:

传送门

哇我是真的觉得这题很妙了!各个方面都很妙啊...

首先有一个很重要的结论:最优线一定可以通过各种变换(旋转/平移)使得经过一条线段的左端点(...并不会证但是挺显然的?

然后看到数据范围<=300,就直接枚举是经过哪个线段的左端点呗

然后怎么算这个线呢?最傻逼的方法当然就再枚下经过哪条线然后算下能经过哪些线算一下balabala的,不详细港了反正是T的

然后就考虑算斜率

ummm下课了我我我我先放代码,over

#include<bits/stdc++.h>
using namespace std;
#define rp(i,x,y) for(register int i=x;i<=y;++i)

const int N=2000+10;
int n,tot,ans;
double eps=1e-8;
struct ed{int x1,x2,y,len;}a[N];
struct xl{double k;int len;}b[N<<1];

inline int read()
{
    char ch=getchar();int x=0;bool y=1;
    while(ch!='-' && (ch<'0' || ch>'9'))ch=getchar();
    if(ch=='-')y=0,ch=getchar();
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
    return y?x:-x;
}
inline bool cmp(xl x,xl y){return x.k<y.k;}
inline void dfs(int x,int y)
{
    int cnt=0;
    rp(i,1,n)
    {
        if(a[i].y!=y)
        {
            b[++cnt].k=(double)(a[i].x1-x)/(a[i].y-y);b[++cnt].k=(double)(a[i].x2-x)/(a[i].y-y);
            if(b[cnt].k>b[cnt-1].k){b[cnt-1].len=a[i].len;b[cnt].len=-a[i].len;b[cnt].k+=eps;}
            else{b[cnt].len=a[i].len;b[cnt-1].len=-a[i].len;b[cnt-1].k+=eps;}
        }
    }
    sort(b+1,b+cnt+1,cmp);
    rp(i,1,cnt)tot+=b[i].len,ans=max(ans,tot);
}

int main()
{
    while(~scanf("%d",&n))
    {
        ans=0;
        rp(i,1,n){a[i].x1=read(),a[i].x2=read(),a[i].y=read();if(a[i].x1>a[i].x2)swap(a[i].x1,a[i].x2);a[i].len=a[i].x2-a[i].x1;}
        rp(i,1,n){tot=a[i].len;ans=max(tot,ans);dfs(a[i].x1,a[i].y);}
        printf("%d\n",ans);
    }
    return 0;
}
哇我真滴觉得!这个方法!太太太妙了!

猜你喜欢

转载自www.cnblogs.com/lqsukida/p/9906341.html