转成二元一次不等式组,然后半平面交。
#include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> #include <cctype> #include <algorithm> #define rep(i, l, r) for(int i=l; i<=r; i++) #define clr(x, c) memset(x, c, sizeof(x)) #define maxn 12345 using namespace std; typedef long long ll; inline int read() { int x=0, f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();} while (isdigit(ch)) x=x*10+ch-‘0‘, ch=getchar(); return x*f; } struct line{ll b, k; int n;} l[maxn]; bool cmp(line a, line b){return a.k>b.k || (a.k==b.k && a.b>b.b);} int n, v[maxn], tot; inline ll Get(line x, line y, line z){return (y.b-x.b)*(y.k-z.k)-(z.b-y.b)*(x.k-y.k);} int main() { n=read(); rep(i, 1, n) l[i].b=read(); rep(i, 1, n) l[i].k=read(); rep(i, 1, n) l[i].n=i; sort(l+1, l+1+n, cmp); v[++tot]=1; rep(i, 2, n) { if (l[i].k==l[i-1].k && l[i].b==l[i-1].b) {v[++tot]=i; continue;} if (l[i].k==l[i-1].k) continue; while (tot>1) if (Get(l[i], l[v[tot]], l[v[tot-1]])<=0) break; else tot--; v[++tot]=i; } while (tot>1) if (l[v[tot-1]].b-l[v[tot]].b<=0) break; else tot--; rep(i, 1, tot) v[i]=l[v[i]].n; sort(v+1, v+tot+1); printf("%d\n", tot); rep(i, 1, tot) printf("%d%c", v[i], i==tot?‘\n‘:‘ ‘); return 0; }
时间: 2024-12-27 21:57:29