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

参考了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. 第13课 SmartGit程序操作介绍

    http://www.syntevo.com/

  2. Labeling Balls(拓扑)

    http://poj.org/problem?id=3687 看题意看了半天没看懂怎么回事,看完Discuss彻底凌乱了..后来看了题解才懂,就是逆向建图+拓扑排序,建图时要判重边. #include ...

  3. JAVA 中进行网络通信时,通信的程序两端要传输的对象,不仅要序列化,而且这个对象所属的类的名字要完全一样,连包的名字都得一样

    如上图项目目录,这是一个简易的QQ,客户端登录的时候要传输用户信息到服务器验证,所以两端都会用到User类的对象,但一开始我在Server端的包名是com.qq.server.common,两端的报名 ...

  4. POJ 1010 题目翻译+题解

    题目实在是太难懂了,我翻译了一下... STAMPS Description Have you done any Philately lately? 你最近有没有集邮? You have been h ...

  5. B - Chat room

    Problem description Vasya has recently learned to type and log on to the Internet. He immediately en ...

  6. 我的MYSQL学习心得(推荐)

    http://www.cnblogs.com/lyhabc/category/573945.html

  7. 《Linux程序设计》笔记(一)入门

    1. 头文件 使用-I标志来包含头文件. gcc -I/usr/openwin/include fred.c 2. 库文件 通过给出 完整的库文件路径名 或 用-l标志 来告诉编译器要搜索的库文件. ...

  8. SLAM: 图像角点检测的Fast算法(时间阈值实验)

    作为角点检测的一种快速方法,FastCornerDetect算法比Harris方法.SIft方法都要快一些,应用于实时性要求较高的场合,可以直接应用于SLAM的随机匹配过程.算法来源于2006年的Ed ...

  9. C++多个文本读取问题

    同时使用两个 ifstream和 freopen 第二个就会失去效用,不知道错在了哪里! 1. 使用freopen打开: bool CPicToolsDlg::readTxt2Seq( std::st ...

  10. node jsonwebtoken

     jsonwebtoken是node版本的JWT(JSON Web Tokens)的实现.1.什么是JWT?Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于J ...