2 条题解

  • 2
    @ 2023-10-30 18:18:38
    #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
      @ 2024-1-21 16:29:55

      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
      上传者