题目大意:

要完成两种属性p,q的需求,给定n个双属性物品及其单位个物品中含有的属性,要求选择最少的物品来达成属性需求。(可以选择实数个物品)

题解:

实际上是一种属性混合问题

我们知道对于两种双属性物品,按照一定比例融合

可以配置出的物品的属性在二维平面上的分布一定是一条直线

而这条直线由最初的双属性物品所对应的点坐标所确定

扩展到三个物品,我们发现所有可配置的物品构成了一个三角形

扩展到n个物品,我们发现这n个点构成的凸包内的物品一定都可以配置

所以我们求出凸包来

然后我们从原点想我们的需求对应的点连一条射线

我们发现这条射线会交凸包于两点(?)

我们找出横纵坐标最大的点

此时我们知道:一定是使用配置出这个点的比例来乘以一个系数k来达到我们的需求

这个系数k就是我们的答案

完了么????

还没有

上面打了一个问号,其实是那里有一些问题。。。 。。。

我们发现这样做的话正确性不能保证,这条射线也不一定与凸包相交

... ...

所以我们再加两个点\((max{a_i},0)\)和\((0,max{b_i})\)就行了

... ...

这两个点解决了所有的不妥以及不恰当。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 100010;
const double eps = 1e-9;
struct Point{
double x,y;
Point(const double a = .0,const double b = .0){x=a;y=b;}
void print(){
printf("Point (%lf,%lf)\n",x,y);
}
};
typedef Point Vector;
Vector operator + (const Vector &a,const Vector &b){
return Vector(a.x+b.x,a.y+b.y);
}
Vector operator - (const Vector &a,const Vector &b){
return Vector(a.x-b.x,a.y-b.y);
}
double operator * (const Vector &a,const Vector &b){
return a.x*b.y - a.y*b.x;
}
Vector operator * (const Vector &a,const double &b){
return Vector(a.x*b,a.y*b);
}
inline int dcmp(const double &x){
if(x < eps && x > -eps) return 0;
return x > 0 ? 1 : -1;
}
inline bool cmp(const Point &a,const Point &b){
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
int n,m;
Point p[maxn],ch[maxn];
void convex(){
sort(p+1,p+n+1,cmp);m = 0;
for(int i=1;i<=n;++i){
while(m > 1 && dcmp((ch[m] - ch[m-1])*(p[i] - ch[m])) <= 0) -- m;
ch[++m] = p[i];
}int k = m;
for(int i=n-1;i>=1;--i){
while(m > k && dcmp((ch[m] - ch[m-1])*(p[i] - ch[m])) <= 0) -- m;
ch[++m] = p[i];
}swap(n,m);swap(ch,p);
}
Point getPoint(Point p,Vector v,Point q,Vector w){
Vector u = p - q;
double t = (w*u)/(v*w);
return p+v*t;
}
inline double length(const Vector &x){
return sqrt(x.x*x.x+x.y*x.y);
}
#define nx(x) ((x) % n + 1)
bool vis[maxn];
int main(){
int xx,yy;read(n);read(xx);read(yy);
int maxx = 0,maxy = 0;
for(int i=1,x;i<=n;++i){
read(x);p[i].x = x;maxx = max(maxx,x);
read(x);p[i].y = x;maxy = max(maxy,x);
}p[++n] = Point(1.0*maxx,0.0);p[++n] = Point(0.0,1.0*maxy);
convex();Vector v(xx,yy);
Point pos[10];int cnt = 0;
for(int i=1;i<=n;++i){
if(dcmp(v*p[i]) == 0){
vis[i] = true;
pos[cnt++] = p[i];
}
}
for(int i=1;i<=n;++i){
if(vis[i] || vis[nx(i)]) continue;
Point a = p[i],b = p[nx(i)];
if(dcmp(a*v)*dcmp(b*v) <= 0){
pos[cnt++] = getPoint(Point(0,0),v,a,b-a);
}
}
if(cmp(pos[0],pos[1])) swap(pos[0],pos[1]);
double ans = length(v)/length(pos[0]);
printf("%.10lf\n",ans);
getchar();getchar();
return 0;
}

CodeForces - 605C 凸包+直线与凸包判交的更多相关文章

  1. Codeforces 605C Freelancer's Dreams 凸包 (看题解)

    Freelancer's Dreams 我们把每个二元组看成是平面上的一个点, 那么两个点的线性组合是两点之间的连线, 即x * (a1, b1) + y * (a1, b1) && ...

  2. Codeforces 1017E The Supersonic Rocket 凸包,计算几何,字符串,KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1017E.html 题目传送门 - CF1017E 题意 给定两个点集,并构成两个凸包. 问这两个凸包是否可 ...

  3. (线段判交的一些注意。。。)nyoj 1016-德莱联盟

    1016-德莱联盟 内存限制:64MB 时间限制:1000ms 特判: No通过数:9 提交数:9 难度:1 题目描述: 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们 ...

  4. (叉积,线段判交)HDU1086 You can Solve a Geometry Problem too

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  5. OpenCASCADE直线与平面求交

    OpenCASCADE直线与平面求交 在<解析几何>相关的书中都给出了直线和平面的一般方程和参数方程.其中直线的一般方程有点向式形式的. 由于过空间一点可作且只能作一条直线平行于已知直线, ...

  6. [codeforces/gym/101350/L]维护“凸包”

    题目链接:http://codeforces.com/gym/101350/problems 给定n个墙,每个墙有一个高度,要支持动态修改墙的高度和查询这个“容器”能盛多少水. (队友)观察发现,能盛 ...

  7. $bzoj1007-HAOI2008$ 水平可见直线 下凸包

    题面描述 在\(xOy\)直角坐标平面上有\(n\)条直线\(L_1,L_2,...,L_n\),若在\(y\)值为正无穷大处往下看,能见到\(L_i\)的某个子线段,则称\(L_i\)为可见的,否则 ...

  8. Codeforces 1255F Point Ordering(凸包+叉积)

    我们随机选取点1,2作为凸包的一个分割线,那么我们可以直接枚举剩下n-2个点找到他们和向量1-2的叉积大小与正负,然后我们可以根据叉积的正负,先将他们分割出两个区域,在向量1-2的下方还是上方,接下来 ...

  9. 【BZOJ】1007: [HNOI2008]水平可见直线(凸包)

    题目 传送门:QWQ 分析 在下面维护一个凸壳 好久没写博客了...... 代码 #include <bits/stdc++.h> using namespace std; ; ,INF= ...

随机推荐

  1. lua(仿类)

    Account = { balance = } function Account:deposit(v) self.balance = self.balance + v end function Acc ...

  2. 博弈SG函数

    转自:Sprague-Grundy Function-SG函数--博弈论(3) 公平游戏的Sprague-Grundy定理 公平游戏是一种双人游戏,在游戏中双方都有完整的信息,没有牵涉,任何状态的合法 ...

  3. 【BZOJ3563/3569】DZY Loves Chinese II 线性基神题

    [BZOJ3563/3569]DZY Loves Chinese II Description 神校XJ之学霸兮,Dzy皇考曰JC. 摄提贞于孟陬兮,惟庚寅Dzy以降. 纷Dzy既有此内美兮,又重之以 ...

  4. visual studio2017 无法添加引用 未能加载包ReferenceManagerPackage not such interface support 解决方法

    安装完visual studio 2017 后添加引用总是提示 未能加载包ReferenceManagerPackage, 这个问题困扰了两天,直到在网上看到了下面这一段 I just got thi ...

  5. 【python】-- 队列(Queue)、生产者消费者模型

    队列(Queue) 在多个线程之间安全的交换数据信息,队列在多线程编程中特别有用 队列的好处: 提高双方的效率,你只需要把数据放到队列中,中间去干别的事情. 完成了程序的解耦性,两者关系依赖性没有不大 ...

  6. 4.对urls.py的解释

    解释: 路由配置文件(URL分发器),它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表.就是以这种方式告诉Django对于每个URL的处理类.Django启动的时候回去加载urls. ...

  7. java基础入门之九九乘法表

    /* 自学java 九九乘法表 Power by Stuart Date: 2015.4.23 */public class Math { public static void main (Strin ...

  8. 【TFS】解决TFS编译中文乱码问题

    前言; TFS2018做程序集成非常方便,线上编译然后直接生成docker镜像,但是在使用过程中遇到编译窗口中文乱码的问题,这个问题找了好久没人知道怎么解决.如下: 这个问题不解决,每次编译失败,研发 ...

  9. androidAndroid开发学习--Ionic+Cordova 环境搭建

    我们看 Ionic 能给我们提供什么?  一个样式库,你可以使用它 来 装饰你的 HTML 网页 ,看起来 想 移动程序的 界面,什么 header .content.footer.grid.list ...

  10. [转] 在Mac上搭建React Native开发环境

    原文链接: http://blog.csdn.net/xiangzhihong8/article/details/53914336 概述 前面我们介绍过在window环境下开发React Native ...