CodeForces 995C Leaving the Bar 随机算法+贪心

C. Leaving the Bar time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

For a vector v=(x,y)v→=(x,y), define |v|=x2+y2|v|=x2+y2.

Allen had a bit too much to drink at the bar, which is at the origin. There are nn vectors v1,v2,,vnv1→,v2→,⋯,vn→. Allen will make nn moves. As Allen’s sense of direction is impaired, during the ii-th move he will either move in the direction vivi→ or vi−vi→. In other words, if his position is currently p=(x,y)p=(x,y), he will either move to p+vip+vi→ or pvip−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 pp satisfies |p|1.5106|p|≤1.5⋅106 so that he can stay safe.

Input

The first line contains a single integer nn (1n1051≤n≤105) — the number of moves.

Each of the following lines contains two space-separated integers xixi and yiyi, meaning that vi=(xi,yi)vi→=(xi,yi). We have that |vi|106|vi|≤106 for all ii.

Output

Output a single line containing nn integers c1,c2,,cnc1,c2,⋯,cn, each of which is either 11 or 1−1. Your solution is correct if the value of p=ni=1civip=∑i=1ncivi→, satisfies |p|1.5106|p|≤1.5⋅106.

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

Examples
input Copy

3
999999 0
0 999999
999999 0
output Copy

1 1 -1 

input Copy

1
-824590 246031
output Copy

1 

input Copy

8
-67761 603277
640586 -396671
46147 -122580
400 914208
569609 -2112
131792 309779
5272 721899
-850150 -486293
output Copy

1 1 1 1 1 1 1 -1 

啊!随机算法什么东西!我从未见过如此骚气的操作!这可真是艺高人胆大,不怕超时的。。。但除此之外别无他法。总之是对每一个向量使用贪心让他离远点更近,然后随机改变向量的顺序,再贪心,直到贪出正确结果为止。这个真的好骚气啊!

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<cmath>
using namespace std;

const long long maxx=2.25e12;

struct v{
    long long x,y;
    int id;
}vs[100005];

int n;
int ans[100005];

int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++)
    {
        scanf("%lld%lld",&vs[i].x,&vs[i].y);
        vs[i].id=i;
    }
    long long sumx=0; long long sumy=0;
    while (1)
    {
        sumx=0; sumy=0;
        random_shuffle(vs+1,vs+1+n);
        for (int i=1; i<=n; i++)
        {
            long long tmp1=(sumx+vs[i].x)*(sumx+vs[i].x)+(sumy+vs[i].y)*(sumy+vs[i].y);
            long long tmp2=(sumx-vs[i].x)*(sumx-vs[i].x)+(sumy-vs[i].y)*(sumy-vs[i].y);
            if (tmp1>tmp2)
            {
                sumx-=vs[i].x; sumy-=vs[i].y; ans[vs[i].id]=-1;
            }else
            {
                sumx+=vs[i].x; sumy+=vs[i].y; ans[vs[i].id]=1;
            }
        }
        if (sumx*sumx+sumy*sumy<=maxx)
        {
            break;
        }
    }
    for (int i=1; i<=n; i++)
        printf("%d ",ans[i]);
    return 0;
}

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/weixin_39399748/article/details/80927378
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞