凸包算法前的预处理,可以极角排序,也可以按X,Y轴排序,
极角排序需要找到角落里的一个点,Xy轴排序要跑两遍凸包
而本题的要求只要一个上半凸包,并且有X轴从小到大以及字典序限制,完全符合xy排序,直接一个循环就过了
坑点:我输出了整个数组的大小,然后完全无视了,wa了12发orz
学会了cmd 的fc来比较文件,多校赛数据都是20M的orz
#define _CRT_SECURE_NO_WARNINGS #include<cmath> #include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> #include<stack> #include<vector> #include<string.h> #include<queue> #include<string> #include<set> #include<time.h> using namespace std; #define rep(i,t,n) for(int i =(t);i<=(n);++i) #define per(i,n,t) for(int i =(n);i>=(t);--i) #define mmm(a,b) memset(a,b,sizeof(a)) #define eps 1e-6 #define pb push_back const int maxn = 2e5 + 10; const int inf = 1e7 + 5;//0x7fffffff; //无限大 const int MOD = 1013; typedef long long ll; struct V { ll x, y; int rk; //V() {} void sc() { scanf("%lld%lld", &x, &y); } V(ll a=0, ll b=0,int rk=0) : x(a), y(b),rk(rk) { } V operator+(V o) { return V(x + o.x, y + o.y); } V operator-(V o) { return V(x - o.x, y - o.y); } double L() { return sqrt(x * x + y * y); } V N() { double l = L(); return V(x / l, y / l); } V rot(double th) { return V(x * cos(th) - y * sin(th), x * sin(th) + y * cos(th)); } V operator*(ll z) { return V(x * z, y * z); } ll operator*(V o) { return x * o.x + y * o.y; } ll operator|(V o) { return 1ll*x * o.y - 1ll*o.x * y; } bool operator ==(V o) { return x == o.x&&y == o.y; } void pr() { printf("%lld %lld ", x, y); } } p[maxn], P[maxn]; int n, top, head; bool cmp(V A, V B) { if (A.x != B.x)return A.x < B.x; if (A.y != B.y)return A.y > B.y; return A.rk < B.rk; } void smain() { int t; cin >> t; while (t--) { cin >> n; rep(i, 1, n) { p[i].sc(); p[i].rk = i; } top = 0; sort(p + 1, p + 1 + n, cmp); P[1] = p[1], P[2] = p[2]; top = 2; rep(i, 3, n) { if (p[i] == P[top])continue; while ( top > 1 &&( (((p[i] - P[top]) | (P[top - 1] - P[top])) > 0 )||(((p[i] - P[top]) | (P[top - 1] - P[top]))== 0&&P[top].rk>p[i].rk)) )top--; P[++top] = p[i]; } rep(i, 1, top) { i!=top?printf("%d ", P[i].rk): printf("%d ", P[i].rk); } } cin >> n; } #define ONLINE_JUDGE int main() { //ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE FILE *myfile; myfile = freopen("C:\Users\acm-14\Desktop\test\G.in", "r", stdin); if (myfile == NULL) fprintf(stdout, "error on input freopen "); FILE *outfile; outfile= freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout); if (outfile == NULL) fprintf(stdout, "error on output freopen "); long _begin_time = clock(); #endif smain(); #ifndef ONLINE_JUDGE long _end_time = clock(); printf("time = %ld ms.", _end_time - _begin_time); #endif return 0; } /* 2 3 0 0 1 0 2 0 4 0 0 3 0 2 0 5 0 5 0 0 1 3 2 1 4 4 5 0 //1 2 4 5 */