• 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 }
     
  • 相关阅读:
    判断点是否在一个任意多边形中
    linux 内存布局以及tlb更新的一些理解
    java(内部类)
    java(面向对象 )
    java(数组及常用简单算法 )
    java(运算符,控制流程语句,函数 )
    deep-in-es6(七)
    Java(标识符,关键字,注释,常量,变量)
    MarkDown study:
    *LeetCode--Ransom Note
  • 原文地址:https://www.cnblogs.com/five20/p/9372718.html
Copyright © 2020-2023  润新知