这道题,说实话,细节很多。不过,我没想到,光细节就能搞死人了。。。

参考了http://www.cppblog.com/varg-vikernes/archive/2010/03/12/109559.html

首先,要把所有牛放到坐标系上来表示。目的,就是求出包含最多点的直角三角形。
直角三角形的两条直角边上都必须有点,也就是一组牛中的具有最小height的点和具有最小width的点。
直角三角形的边长也是固定的,cw = C/B,ch = C/A。这个还好说,从那个限制条件可以推出来的。初中都学过,呵呵。

Step1:求出经过一个点的所有可能存在的三角形。
其实也就是在该点下方的灰色区域中选择点来确定一个三角形。

Step2:求出经过一个点的所有可能存在的三角形中,最多包含的点数。
解法相当精妙。

求一个三角形内的点数,可以分解为一个矩形内的点数减去一个梯形内的点数。

用这个方法,求出最上面那个三角形的点数之后。可以继续递推得到下面其他三角形的点数。

也就是加上一个矩形,再减去一个梯形。
如果点按照高度排序以后,那么后面矩形里的点一定是后出现的。这样就可以做到随时增加矩形。
但是减去梯形这个操作,就难理解一点,把点按照A*H + B*W来排序,就能保证后面梯形里的点一定是后出现的。

可见,A*H + B*W 值的大小决定了他们的位置分布。完全可以保证这个顺序。
这种数形结合的方法实在是相当精妙!

在退出点的时候,我选择用优先队列来做。写得很锉

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <cctype>
#include <vector>
#include <queue>
#include <algorithm>
#define LL unsigned __int64
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; const int N=; struct Node{
int x,y;
int AH;
bool operator <(const Node &a) const {
if(y>a.y) return true;
else if(y==a.y){
if(x<a.x) return true;
}
return false;
}
}node[N];
int n,A,B,C,xh,yh;
struct Int_Node{
int AH;
Int_Node(int x){AH=x;};
bool operator<(const Int_Node &a)const {
if(AH<a.AH) return true;
return false;
}
};
priority_queue<Int_Node>Q; int main(){
int ah,ans=;
while(scanf("%d",&n)!=EOF){
ans=;
scanf("%d%d%d",&A,&B,&C);
yh=C/B; xh=C/A;
for(int i=;i<n;i++){
scanf("%d%d",&node[i].x,&node[i].y);
node[i].AH=A*node[i].x+B*node[i].y;
}
sort(node,node+n);
for(int i=;i<n;i++){
int xmin=node[i].x,ymin=node[i].y;
ah=A*xmin+B*ymin;
int j;
for(j=;j<i;j++){
if(node[j].y==ymin) break;
if(node[j].x<=xmin+xh&&node[j].y<=ymin+yh&&node[j].x>=xmin)
if(A*node[j].x+B*node[j].y-ah<=C)
Q.push(Int_Node(node[j].AH));
}
for(j;j<n&&node[j].x<=xmin+xh&&node[j].y==ymin&&node[j].x>=xmin;j++)
Q.push(Int_Node(node[j].AH));
int ts=Q.size();
ans=max(ans,ts);
for(int k=j;node[k].y+yh>=node[i].y&&k<n;k++){
if(node[k].y<ymin){
ymin=node[k].y;
ah=A*xmin+B*ymin;
int p;
for(p=k;node[p].y==ymin&&p<n;p++){
if(node[p].x<=xmin+xh&&node[p].x>=xmin){
Q.push(Int_Node(node[p].AH));
}
}
k=p-;int tmp;
while(!Q.empty()){
tmp=Q.top().AH;
if(tmp-ah>C){
Q.pop();
}
else
break;
}
ts=Q.size();
ans=max(ans,ts);
}
}
while(!Q.empty())
Q.pop();
}
printf("%d\n",ans);
}
return ;
}

POJ 2008的更多相关文章

  1. POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / SCU 1132 Invitation Cards / ZOJ 2008 Invitation Cards / HDU 1535 (图论,最短路径)

    POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / ...

  2. HDU 2494/POJ 3930 Elevator(模拟)(2008 Asia Regional Beijing)

    Description Too worrying about the house price bubble, poor Mike sold his house and rent an apartmen ...

  3. POJ 1511 Invitation Cards (ZOJ 2008) 使用优先队列的dijkstra

    传送门: http://poj.org/problem?id=1511 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1008 ...

  4. POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳

    题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...

  5. POJ 3322(广搜)

    ---恢复内容开始--- http://poj.org/problem?id=3322 题意:http://jandan.net/2008/01/24/bloxorz.html就是这个鬼游戏 我也是郁 ...

  6. (转)POJ题目分类

    初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推. ...

  7. poj分类

    初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      ( ...

  8. [双连通分量] POJ 3694 Network

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9434   Accepted: 3511 Descripti ...

  9. Poj(3686),最小权匹配,多重匹配,KM

    题目链接 The Windy's | Time Limit: 5000MS | Memory Limit: 65536K | | Total Submissions: 4939 | Accepted: ...

随机推荐

  1. bzoj4004 [JLOI2015]装备购买——线性基+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004 今天讲课讲到的题,据说满足拟阵的性质,所以贪心是正确的: 总之就贪心,按价格从小到大排 ...

  2. DCloud-MUI:窗口管理

    ylbtech-DCloud-MUI:窗口管理 通过预加载解决切页白屏问题,通过封装原生动画解决SPA模式的动画卡顿 1.返回顶部 1.页面初始化 在app开发中,若要使用HTML5+扩展api,必须 ...

  3. 用JS将指定时间转化成用户当地时区的时间

    公司的项目是面向海外用户的,但是最初的设计没考虑到时差问题,存入数据库的时间都是东八区的时间,导致现在补救有点坑爹...... 有一个需求是,产品详细页需要注明此款产品的开售时间,当海外的用户来访问这 ...

  4. PCB 后台自动系统集成与邮件推送实现

    在PCB行业中,工程系统是主要数据生产者,而这些数据不仅仅给自己系统使用呀,我们需要将数据传递到各系统,才达到各系统共同协作的目的. 这里以问答方式对实现方式进行讲解.呵呵呵! 后台自动集成问题解答: ...

  5. PCB拼板之单一矩形排样算法

    算法实现相关内容整理如下: 一.排样变量与关系 此算法,基于固定4边的尺寸遍历每个单只板的长宽得到最优解. 二.条件约束 基本约束条件(参考上图变量) 三.排样图形相同类型规律 由于计算量大,为了有效 ...

  6. 遍历WPF DataGrid单元格

    using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Media; ...

  7. C#:设置webBrowser框架与系统相对应的IE内核版本

    通常情况下,我们直接调用C#的webBrowser控件,默认的浏览器内核是IE7.  那么如何修改控件调用的默认浏览器版本呢? /// <summary> /// 修改注册表信息来兼容当前 ...

  8. Java 精度控制

    四舍五入,保留两位小数 (找了很多种方法,都有问题,测试得出下面这种方式是可用的) String str="0.235"; String.format("%.2f&quo ...

  9. SQLServer2008 关于while循环

    有这样一个表tbl id  code name 11   a      aa/bb/cc 22   b      ee/rr/tt 需要将name段根据‘/’拆分开来,变成新的数据行 即: id  c ...

  10. Java中last_insert_id的使用

    last_insert_id的作用是:在当前表中的主键是自增时,插入一条新记录的同时使用last_insert_id可以获取当前的新记录的主键id. 下面是一个例子: import java.sql. ...