首页 > 其他分享 >bzoj 1007: [HNOI2008]水平可见直线(模拟栈)

bzoj 1007: [HNOI2008]水平可见直线(模拟栈)

时间:2023-06-02 18:38:46浏览次数:69  
标签:直线 斜率 1007 l2 l1 HNOI2008 include bzoj


http://www.lydsy.com/JudgeOnline/problem.php?id=1007


1007: [HNOI2008]水平可见直线


Time Limit: 1 Sec  Memory Limit: 162 MB

Submit: 7644  Solved: 2922

[Submit][Status][Discuss]

Description


  在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为
可见的,否则Li为被覆盖的.
例如,对于直线:
L1:y=x; L2:y=-x; L3:y=0
则L1和L2是可见的,L3是被覆盖的.
给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线.


Input


  第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi


Output


  从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格


Sample Input


3
-1 0
1 0
0 0


Sample Output


1 2


【解析】:

用数组模拟栈,先按斜率排序。

其实最后看到的是一个碗,所以,斜率是递增的,如果存在斜率相等的,在下方的直接舍去。

交点的x坐标也是递增的。

所以,如果当前加入的直线,与栈顶直线的交点x<栈顶与栈中第二直线交点x,则覆盖上一条直线

否则,这条直线加入栈

最后把栈中的直线编号按顺序输出即可。

【代码】:

#include <stdio.h>
#include <stdlib.h>  
#include <string.h>  
#include <algorithm> 
using namespace std;
struct line{//存直线
	double a,b;
	int dex;
}l[52020],s[52020];//l存直线,s模拟栈 
int n,ans[52020];
bool cmp(line l1,line l2)//按斜率从小到大排序
{
	if(l1.a==l2.a)return l1.b>l2.b;
	return l1.a<l2.a;
}
double getx(line l1,line l2)//求两直线交点的x坐标 
{
	return (l2.b-l1.b)/(l1.a-l2.a);
}
void output(int top)//输出 
{
	memset(ans,0,sizeof(ans));
	for(int i=1;i<=top;i++)
		ans[i]=s[i].dex;
	sort(ans+1,ans+1+top);
	for(int i=1;i<=top;i++)
		printf("%d ",ans[i]);
	puts("");
}
void solve()
{
	int top=0;//s的下标
	s[++top]=l[1];
	for(int i=2;i<=n;i++)//遍历直线
	{
		if(l[i].a==l[i-1].a)continue;//会被覆盖
		while(top>1&&getx(l[i],s[top])<getx(s[top],s[top-1]))top--;//可以覆盖上一条直线 
		s[++top]=l[i];
	}
	output(top);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lf%lf",&l[i].a,&l[i].b);
		l[i].dex=i;
	}
	sort(l+1,l+1+n,cmp);
	solve();
}





标签:直线,斜率,1007,l2,l1,HNOI2008,include,bzoj
From: https://blog.51cto.com/u_16125110/6404520

相关文章

  • bzoj1001 [BeiJing2006]狼抓兔子(网络流dinic算法||最短路spfa)
    http://www.lydsy.com/JudgeOnline/problem.php?id=10011001:[BeiJing2006]狼抓兔子TimeLimit: 15Sec  MemoryLimit: 162MBSubmit: 24017  Solved: 6068[Submit][Status][Discuss]Description现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓......
  • Luogu P1007 独木桥
    题目描述link思路找到独木桥的中间位置,最少时间考虑在端点左侧的,向左走,在端点右侧的向右走.最多时间考虑在端点左侧的向右走,在端点右侧的向左走.最少时间即为最优情况下最多的时间,最多时间即为最差情况下的最多时间Code#include<cstdio>#include<algorithm>......
  • BZOJ1503(Splay)
    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 #include<iostream>#include<string.h>#include<stdio.h>usingnamespacestd;structNode{intval,size,cnt,lazy;Node*pre,*ch[2];Node(){size=lazy......
  • [BZOJ4407]于神之怒加强版 CODE
    #include<bits/stdc++.h>#definelllonglong#defineFor(i,a,b)for(lli=(a);i<=(b);++i)#defineRep(i,a,b)for(lli=(a);i>=(b);--i)constllN=1e6+10;usingnamespacestd;constllmod=1e9+7;llvis[N],tot,p[N];voidinit(lln){//质数筛For......
  • 【BZOJ2007】【NOI2010】海拔(对偶图,最短路)
    DescriptionYT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域。简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形。从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向道路连接主干道上两个相邻的交叉路口。下图为......
  • 【BZOJ4241】【回滚莫队模板题】历史研究
    Description给定一个序列,每次询问区间[l,r][l,r]内,所有权值与其出现次数的乘积的最大值。Solution回滚莫队模板题。将询问以左端点所在块为第一关键字,右端点为第......
  • GYM100722C - Ticket to Ride
    首先考虑\(dp_{i,msk}\)表示当前连通了\(msk\)中所有关键点,并且当前连通的非关键点包含\(i\)的最小代价。然后考虑如何转移。我们先用\(Floyd\)预处理所有点对之间的最短路\(dist_{i,j}\)。同时,每次选取的两个用于合并的关键点集合一定没有交集,所以我们可以直接枚举子集......
  • PAT Advanced 1007. Maximum Subsequence Sum
    PATAdvanced1007.MaximumSubsequenceSum1.ProblemDescription:Givenasequenceof\(K\)integers{\(N_1,N_2,...,N_K\)}.Acontinuoussubsequenceisdefinedtobe{\(N_i,N_{i+1},...,N_j\)}where\(1≤i≤j≤K\).TheMaximumSubsequencei......
  • [Luogu-P1007]题解(C++)
    PartIPreface原题目(Luogu)PartIISketch给定一个正整数\(L\),表示独木桥长度。给定一个正整数\(N\),表示桥上士兵的数量。给定\(N\)个整数,分别表示每个士兵的坐标。规定走到\(0\)坐标或\(L+1\)的位置为下桥,两个士兵相遇时不能走过去,他们会各自回头走。求出所有士......
  • 「BZOJ2144」跳跳棋-题解
    「BZOJ2144」跳跳棋个人评价挺好的一道题,难点在于想到树这个结构和建树1题面跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移......