Codeforces 996E Leaving the Bar (随机化)

题目连接:Leaving the Bar

题意:给你n个向量,你可以加这个向量或减这个向量,使得这些向量之和的长度小于1.5e6。

题解: 按照正常的贪心方法,最后的结果有可能大于1.5e6 。这里我们可以加一些随机性,多次贪心,直到结果满足题意。正解是每三个向量中都能找到两个向量合起来 <= 1e6,然后不断合并,最后只会剩下一个或者两个向量,如果一个向量肯定 <= 1e6, 如果是两个向量一定 <= 1.5 * 1e6。这是我第一遇到随机化的题~~~

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define fi first
 4 #define se second
 5 typedef long long LL;
 6 typedef pair<int,int> P;
 7 typedef pair<LL,LL> PL;
 8 const int MAX_N =1e5+9;
 9 int N,M,T,S;
10 struct node{
11     int f,s,v;
12 };
13 node vec[MAX_N];
14 int res[MAX_N];
15 int main()
16 {
17     while(cin>>N){
18         for(int i=0;i<N;i++){
19             scanf("%d%d",&vec[i].f,&vec[i].s);
20             vec[i].v = i;
21         }
22         LL ti = 1500000;
23         while(1){
24             LL x = 0;
25             LL y = 0;
26             for(int i=0;i<N;i++){
27                 if((x + vec[i].f)*(x+vec[i].f) + (y+vec[i].s)*(y+vec[i].s) <=
28                   (x - vec[i].f)*(x-vec[i].f) + (y-vec[i].s)*(y-vec[i].s)  ){
29                     x += vec[i].f;
30                     y += vec[i].s;
31                     res[vec[i].v] = 1;
32                 }
33                 else{
34                     x -= vec[i].f;
35                     y -= vec[i].s;
36                     res[vec[i].v] = -1;
37                 }
38             }
39             if(x*x+y*y <= ti*ti){
40                 for(int i=0;i<N;i++){
41                     printf("%d ",res[i]);
42                 }
43                 cout<<endl;
44                 break;
45             }
46             random_shuffle(vec, vec+N);
47         }
48     }
49     return 0;
50 }

 

posted @ 2018-08-23 16:33  会打架的程序员不是好客服  阅读(360)  评论(0编辑  收藏  举报