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 }
posted @ 2019-11-23 17:03  DD_BOND  阅读(353)  评论(0编辑  收藏  举报