2 条题解
-
2
#include<bits/stdc++.h> using namespace std; const int N=5e4+5; struct node{ int k,b,id; }a[N]; bool cmp(node n1,node n2){ if(n1.k==n2.k){ return n1.b>n2.b; } return n1.k>n2.k; } int top,sta[N],ans[N]; double calc(int x,int y){ return 1.0*(a[y].b-a[x].b)/(a[x].k-a[y].k); } int main(){ int n;scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].k,&a[i].b); a[i].id=i; } sort(a+1,a+n+1,cmp); top=1;sta[1]=1; for(int i=2;i<=n;i++){ if(a[i].k==a[i-1].k)continue; while(top>1&&calc(sta[top-1],sta[top])<=calc(sta[top],i))top--; sta[++top]=i; } for(int i=1;i<=top;i++){ ans[i]=a[sta[i]].id; } sort(ans+1,ans+top+1); for(int i=1;i<=top;i++){ printf("%d ",ans[i]); } return 0; }
-
0
1.对于斜率相同的两条直线截距小的被覆盖。
2.对于斜率不同的三条直线,如果一条直线不可见
那么必定是斜率最大和斜率最小的覆盖另外一条线段
同时斜率最大和斜率最小的直线的交点在另一条线段的上方
根据这个性质,通过排序和单调栈即可维护可见直线。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N=50010; struct Node{ int k,b,id; friend bool operator<(Node a,Node b){ if(a.k!=b.k)return a.k<b.k; return a.b>b.b; } }l[N]; double Cx(Node a,Node b){ return 1.0*(a.b-b.b)/(b.k-a.k); } int n,m; int st[N],top; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&l[i].k,&l[i].b); l[i].id=i; } sort(l+1,l+n+1); for(int i=1;i<=n;i++){ if(l[i].k!=l[i-1].k) l[++m]=l[i]; } n=m; st[top=1]=1; for(int i=2;i<=n;i++){ while(top>1&&Cx(l[i],l[st[top]])<=Cx(l[st[top]],l[st[top-1]]))top-=1; st[++top]=i; } for(int i=1;i<=top;i++) st[i]=l[st[i]].id; sort(st+1,st+top+1); for(int i=1;i<=top;i++) printf("%d ",st[i]); return 0; }
- 1
信息
- ID
- 1007
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 56
- 已通过
- 32
- 上传者