Codeforces 1255F Point Ordering(凸包+叉积)
我们随机选取点1,2作为凸包的一个分割线,那么我们可以直接枚举剩下n-2个点找到他们和向量1-2的叉积大小与正负,然后我们可以根据叉积的正负,先将他们分割出两个区域,在向量1-2的下方还是上方,接下来找到距离向量1-2最高的点id1和最低点id2,接下来在通过向量id1-1再次分割再上方的点,同样最id2-1分割下方的点,这样就可以分割出了四个区域,最后通过叉积所得的值进行排序,因为这四个区域中的高度要么是递增要么是递减,因为题目严格保证是没有三点共线,那么这样就可以还原出来一个凸包。
1 // ——By DD_BOND 2 3 #include<bits/stdc++.h> 4 5 #define fi first 6 #define se second 7 #define MP make_pair 8 #define pb push_back 9 #define INF 0x3f3f3f3f 10 #define pi 3.1415926535898 11 #define lowbit(a) (a&(-a)) 12 #define lson l,(l+r)/2,rt<<1 13 #define rson (l+r)/2+1,r,rt<<1|1 14 #define Min(a,b,c) min(a,min(b,c)) 15 #define Max(a,b,c) max(a,max(b,c)) 16 #define debug(x) cerr<<#x<<"="<<x<<"\n"; 17 18 //#pragma GCC optimize(3) 19 //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") 20 21 using namespace std; 22 23 typedef long long ll; 24 typedef pair<int,int> P; 25 typedef pair<ll,ll> Pll; 26 typedef unsigned long long ull; 27 28 const int seed=131; 29 const ll LLMAX=2e18; 30 const int MOD=1e9+7; 31 const double eps=1e-8; 32 const int MAXN=1e6+10; 33 const int hmod1=0x48E2DCE7; 34 const int hmod2=0x60000005; 35 36 inline ll sqr(ll x){ return x*x; } 37 inline int sqr(int x){ return x*x; } 38 inline double sqr(double x){ return x*x; } 39 ll __gcd(ll a,ll b){ return b==0? a: __gcd(b,a%b); } 40 ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;} 41 inline int dcmp(double x){ if(fabs(x)<eps) return 0; return (x>0? 1: -1); } 42 43 ll val[MAXN]; 44 vector<Pll>l,r; 45 vector<ll>ans,down,up; 46 47 int main(void) 48 { 49 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 50 // freopen("/My_Mac/Resource/Project__C++/testdata.in","r",stdin); 51 //freopen("/My_Mac/Resource/Project__C++/testdata.out","w",stdout); 52 int n; cin>>n; 53 ans.pb(0); ans.pb(1); 54 ll MAX=0,MIN=0,id1=1,id2=1; 55 for(int i=3;i<=n;i++){ 56 ll f=0,area=0; 57 cout<<"1 1 2 "<<i<<endl; cout.flush(); cin>>area; 58 cout<<"2 1 2 "<<i<<endl; cout.flush(); cin>>f; 59 val[i]=area; area*=f; 60 if(area>0) up.pb(i); 61 else down.pb(i); 62 if(area>MAX) MAX=area,id1=i; 63 if(area<MIN) MIN=area,id2=i; 64 } 65 for(auto i:down){ 66 ll f; 67 if(i==id2) continue; 68 cout<<2<<' '<<id2<<' '<<1<<' '<<i<<endl; cout.flush(); cin>>f; 69 if(f==1) l.pb(Pll(val[i],i)); 70 else r.pb(Pll(val[i],i)); 71 } 72 sort(l.begin(),l.end()); 73 for(auto i:l) ans.pb(i.se); 74 if(id2!=1) ans.pb(id2); 75 sort(r.begin(),r.end(),greater<Pll>()); 76 for(auto i:r) ans.pb(i.se); 77 ans.pb(2); 78 l.clear(); r.clear(); 79 80 for(auto i:up){ 81 if(i==id1) continue; 82 ll f; 83 cout<<2<<' '<<id1<<' '<<1<<' '<<i<<endl; cout.flush(); cin>>f; 84 if(f==1) l.pb(Pll(val[i],i)); 85 else r.pb(Pll(val[i],i)); 86 } 87 sort(l.begin(),l.end()); 88 for(auto i:l) ans.pb(i.se); 89 if(id1!=1) ans.pb(id1); 90 sort(r.begin(),r.end(),greater<Pll>()); 91 for(auto i:r) ans.pb(i.se); 92 l.clear(); r.clear(); 93 for(auto i:ans) cout<<i<<' '; 94 cout.flush(); 95 return 0; 96 }