1. 程式人生 > 實用技巧 >團體程式設計天梯賽 長城

團體程式設計天梯賽 長城

https://pintia.cn/problem-sets/994805046380707840/problems/994805050277216256

從右向左列舉所有的點

假設列舉到i,考慮讓哪個點看到i最優

如上圖,當ik的斜率大於等於ij的斜率時,對於i點來說j是不需要的

所以對於每個點要維護一個斜率單調遞增的棧,每次的棧頂的點就是要能看到當前點的點

#include<cstdio>

using namespace std;

#define N 100001

int x[N],y[N];
int st[N],top;
bool use[N];

bool check(int i,int j,int
k) { long long a=1ll*(y[i]-y[k])*(x[j]-x[k]); long long b=1ll*(y[j]-y[k])*(x[i]-x[k]); return a<=b; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d%d",&x[i],&y[i]); st[top=1]=1; for(int i=2;i<=n;++i) { if(top>=2
) { while(top>=2 && check(i,st[top],st[top-1])) top--; use[st[top]]=true; } st[++top]=i; } int m=0; for(int i=2;i<n;++i) if(use[i]) ++m; printf("%d",m); }