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} pvi .

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 p1.5106 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 1n105 ) — 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 vi106 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 p1.5106 .

It can be shown that a solution always exists under the given constraints.

输入输出样例

输入样例#1: 
3
999999 0
0 999999
999999 0
输出样例#1: 
1 1 -1 
输入样例#2: 
1
-824590 246031
输出样例#2: 
1 
输入样例#3: 
8
-67761 603277
640586 -396671
46147 -122580
569609 -2112
400 914208
131792 309779
-850150 -486293
5272 721899
输出样例#3: 
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 }
 
原文地址:https://www.cnblogs.com/five20/p/9372718.html