题目连接: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 }