CF995C Leaving the Bar
题目描述
For a vector v⃗=(x,y) \vec{v} = (x, y) v=(x,y) , define ∣v∣=x2+y2 |v| = \sqrt{x^2 + y^2} ∣v∣=x2+y2 .
Allen had a bit too much to drink at the bar, which is at the origin. There are n n n vectors v1⃗,v2⃗,⋯,vn⃗ \vec{v_1}, \vec{v_2}, \cdots, \vec{v_n} v1,v2,⋯,vn . Allen will make n n n moves. As Allen's sense of direction is impaired, during the i i i -th move he will either move in the direction vi⃗ \vec{v_i} vi or −vi⃗ -\vec{v_i} −vi . In other words, if his position is currently p=(x,y) p = (x, y) p=(x,y) , he will either move to p+vi⃗ p + \vec{v_i} p+vi or p−vi⃗ p - \vec{v_i} p−vi .
Allen doesn't want to wander too far from home (which happens to also be the bar). You need to help him figure out a sequence of moves (a sequence of signs for the vectors) such that his final position p p p satisfies ∣p∣≤1.5⋅106 |p| \le 1.5 \cdot 10^6 ∣p∣≤1.5⋅106 so that he can stay safe.
输入输出格式
输入格式:The first line contains a single integer n n n ( 1≤n≤105 1 \le n \le 10^5 1≤n≤105 ) — the number of moves.
Each of the following lines contains two space-separated integers xi x_i xi and yi y_i yi , meaning that vi⃗=(xi,yi) \vec{v_i} = (x_i, y_i) vi=(xi,yi) . We have that ∣vi∣≤106 |v_i| \le 10^6 ∣vi∣≤106 for all i i i .
输出格式:Output a single line containing n n n integers c1,c2,⋯,cn c_1, c_2, \cdots, c_n c1,c2,⋯,cn , each of which is either 1 1 1 or −1 -1 −1 . Your solution is correct if the value of p=∑i=1ncivi⃗ p = \sum_{i = 1}^n c_i \vec{v_i} p=∑i=1ncivi , satisfies ∣p∣≤1.5⋅106 |p| \le 1.5 \cdot 10^6 ∣p∣≤1.5⋅106 .
It can be shown that a solution always exists under the given constraints.
输入输出样例
3
999999 0
0 999999
999999 0
1 1 -1
1
-824590 246031
1
8
-67761 603277
640586 -396671
46147 -122580
569609 -2112
400 914208
131792 309779
-850150 -486293
5272 721899
1 1 1 1 1 1 1 -1
Solution:
本题很玄学,正解不会,直接随机。
用random_shuffle去随机打乱数组,然后贪心,对于第$i$个向量直接在$+1,-1$中选一个使向量长度小的,然后判断向量和的长度是否满足条件就好了。
代码:
1 #include<bits/stdc++.h> 2 #define il inline 3 #define ll long long 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--) 6 using namespace std; 7 const int N=100005; 8 const ll T=1500000*1ll*1500000; 9 ll ans[N]; 10 ll n; 11 struct node{ 12 ll id,x,y; 13 }a[N]; 14 15 il int gi(){ 16 int a=0;char x=getchar();bool f=0; 17 while((x<'0'||x>'9')&&x!='-')x=getchar(); 18 if(x=='-')x=getchar(),f=1; 19 while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar(); 20 return f?-a:a; 21 } 22 23 il ll lala(ll x,ll y){return x*x+y*y;} 24 25 int main(){ 26 srand(time(0)); 27 n=gi(); 28 For(i,1,n) a[i].x=gi(),a[i].y=gi(),a[i].id=i; 29 ll x,y; 30 while(1){ 31 random_shuffle(a+1,a+n+1); 32 x=0,y=0; 33 For(i,1,n) 34 if(lala(x-a[i].x,y-a[i].y)<lala(a[i].x+x,a[i].y+y)) ans[a[i].id]=-1,x-=a[i].x,y-=a[i].y; 35 else ans[a[i].id]=1,x+=a[i].x,y+=a[i].y; 36 if(lala(x,y)<=T) {For(i,1,n) printf("%lld ",ans[i]);break;} 37 } 38 return 0; 39 }