Kickstart2017 RoundB

B.题意: 二维平面上有n个点, 每个点坐标(xi, yi), 权值wi, 问: 在平面上找一点p, 使得 Σwi*max(|X-xi|, |Y-yi|)最小, (X, Y)为p点坐标。求该最小值。

二维空间:

欧几里得距离:d=√(|x1-x2|2+|y1-y2|2)

曼哈顿距离 :d=|x1-x2|+|y1-y2|,到某点的曼哈顿距离为r的点组成一个边长为√2*r的正方形,且边与坐标轴成45度

切比雪夫距离:d=max(|x1-x2|,|y1-y2|),到某点的切比雪夫距离为r的点组成一个边长为2*r的正方形,且边与坐标轴平行

  1. /*
  2. 题解: 赛后看到有不少随机化算法可乱搞过去
  3. 该题是二维平面邮局距离(参见《算法导论》)的变形
  4.  
  5. simple版:一维下, 使得Σwi*|X-xi|最小, 其中所有wi = 1. 答案显然为xi的中位数
  6. middle版:我们可以将wi看成有wi个点重合, 权值均为1, 则可套用simple版解法
  7. hard版:二维下, 使得 Σwi*(|X-xi| +|Y-yi|)最小. X轴, Y轴分开解即可
  8. 此题:我们将整个平面旋转45°即可变为hard版. 为什么?
  9.  
  10. 因为hard中|X-xi| +|Y-yi|表示的边界形状为以(xi, yi)为中心的45°倾斜的正方形
  11. 而本题max(|X-xi|, |Y-yi|)表示的边界形状为以(xi, yi)为中心的正方形
  12. */
  13.  
  14. #include <iostream>
  15. #include <algorithm>
  16. #include <vector>
  17. #include <string>
  18. #include <unordered_set>
  19. #include <unordered_map>
  20. #include <set>
  21. #include <map>
  22. #include <queue>
  23. #include <stack>
  24. #include <functional>
  25. #include <cmath>
  26. #include <string.h>
  27.  
  28. using namespace std;
  29. using ull = unsigned long long;
  30. using ll = long long;
  31. using db = double;
  32. using PII = pair<int, int>;
  33.  
  34. template<typename T>
  35. void print_vec(T& container, const std::string& sep = " "){
  36. for (auto& x: container){
  37. std::cout << x << sep;
  38. }
  39. std::cout << std::endl;
  40. }
  41.  
  42. template<typename T>
  43. void print_map(T& mp){
  44. for(auto& x: mp){
  45. std::cout << x.first << " " << x.second << std::endl;
  46. }
  47. }
  48.  
  49. struct Point{
  50. double x, y, w;
  51. void input(){
  52. cin >> x >> y >> w;
  53. }
  54. double dist(double _x, double _y){
  55. return fabs(x - _x) + fabs(y - _y);
  56. }
  57. void rotate(){
  58. static double ang = 45.0 / * acos(-1.0);
  59. double x1 = x * cos(ang) - y * sin(ang);
  60. double y1 = x * sin(ang) + y * cos(ang);
  61. x = x1 * sin(ang) ;
  62. y = y1 * sin(ang) ;
  63. }
  64. };
  65. struct Problem{
  66.  
  67. int N;
  68. Point p[];
  69. void read(){
  70. cin >> N;
  71. for (int i = ; i < N; i++){
  72. p[i].input();
  73. p[i].rotate();
  74. }
  75. }
  76.  
  77. struct WEIGHT{
  78. double w;
  79. double x;
  80. bool operator<(const WEIGHT& wt) const{
  81. return x < wt.x;
  82. }
  83. };
  84.  
  85. double calc(WEIGHT wt[], int n){
  86. sort(wt, wt + n);
  87. double ans = ;
  88. double cur_x = wt[].x;
  89. double pre_sum = ;
  90. double suf_sum = ;
  91. for (int i = ; i < n; i++){
  92. ans += (wt[i].x - cur_x) * wt[i].w;
  93. suf_sum += wt[i].w;
  94. }
  95. double ret = ans;
  96. for (int i = ; i < n; i++){
  97. double nxt_x = wt[i].x;
  98. suf_sum -= wt[i-].w;
  99. pre_sum += wt[i-].w;
  100. ans -= suf_sum * (nxt_x - cur_x);
  101. ans += pre_sum * (nxt_x - cur_x);
  102. cur_x = nxt_x;
  103. ret = min(ans, ret);
  104. }
  105. return ret;
  106. }
  107. void solve(int ca){
  108. printf("Case #%d: ", ca);
  109.  
  110. WEIGHT vx[], vy[];
  111. for (int i = ; i < N; i++){
  112. vx[i].x = p[i].x;
  113. vx[i].w = p[i].w;
  114. vy[i].x = p[i].y;
  115. vy[i].w = p[i].w;
  116. }
  117. double sum = calc(vx, N) + calc(vy, N);
  118. printf("%.7f\n", sum);
  119. }
  120. };
  121.  
  122. int main(){
  123. int T;
  124. cin >> T;
  125. for (int ca = ; ca <= T; ca++){
  126. Problem p;
  127. p.read();
  128. p.solve(ca);
  129. }
  130. }

附随机化模拟退火算法:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <vector>
  6. #include <map>
  7. #include <set>
  8. #include <climits>
  9. #include <stack>
  10. #include <queue>
  11. #include <ctime>
  12. #include <string>
  13. #include <iostream>
  14. #include <algorithm>
  15. using namespace std;
  16.  
  17. #define MEM(a,b) memset(a,b,sizeof(a))
  18. #define REP(i,n) for(int i=0;i<(n);++i)
  19. #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
  20. #define getmid(l,r) ((l) + ((r) - (l)) / 2)
  21. #define MP(a,b) make_pair(a,b)
  22.  
  23. typedef long long ll;
  24. typedef pair<int,int> pii;
  25. const int INF = ( << ) - ;
  26. const int MAXN = ;
  27. const double cof = 0.5;
  28. const double eps = 1e-;
  29. const double deta = 0.7;
  30.  
  31. int T,N;
  32. double X[MAXN],Y[MAXN], W[MAXN];
  33. int dir[][] = {{-,},{,},{,-},{,}};
  34.  
  35. double Dis(double a1,double b1,double a2,double b2){
  36. return max(abs(a1-a2), abs(b1-b2));
  37. }
  38.  
  39. double Cal(double a,double b){
  40. double res = Dis(a,b,X[],Y[]) * W[];
  41. FOR(i,,N - ) res += Dis(a,b,X[i],Y[i]) * W[i];
  42. return res;
  43. }
  44.  
  45. int main(){
  46. srand((unsigned)time(NULL));
  47. int a,b;
  48. scanf("%d",&T);
  49. FOR(tt,,T){
  50. scanf("%d",&N);
  51. REP(i,N) scanf("%lf%lf%lf",&X[i],&Y[i], &W[i]);
  52. double ans = -,ansx,ansy;
  53. REP(o,){
  54. double sx = rand() % (N + );
  55. double sy = rand() % (N + );
  56. double res = Cal(sx,sy);
  57. double step = N;
  58. while(step > eps){
  59. while(){
  60. bool mov = false;
  61. REP(k,){
  62. double tx = sx + dir[k][] * step;
  63. double ty = sy + dir[k][] * step;
  64. if(tx < - || tx > || ty < - || ty > ) continue;
  65. double tmp = Cal(tx,ty);
  66. if(tmp < res || (double)rand()/INT_MAX > deta){
  67. res = tmp;
  68. sx = tx;
  69. sy = ty;
  70. mov = true;
  71. }
  72. }
  73. if(mov == false) break;
  74. }
  75. step *= cof;
  76. }
  77. if(ans == - || res < ans){
  78. ans = res;
  79. ansx = sx;
  80. ansy = sy;
  81. }
  82. }
  83. printf("Case #%d: %.6lf\n", tt, ans);
  84. //printf("The safest point is (%.1f, %.1f).\n",ansx,ansy);
  85. }
  86. return ;
  87. }

Google题解的更多相关文章

  1. 2017 google Round D APAC Test 题解

    首先说明一下:我只是用暴力过了4道题的小数据,就是简单的枚举,大数据都不会做!下面的题解,是我从网上搜到的解答以及查看排行榜上大神的答案得出来的. 首先贴一下主要的题解来源:http://codefo ...

  2. Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解

    Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解 题目地址:https://codingcompetitions.withgoogle.com/kickstar ...

  3. Google kickstart 2022 Round A题解

    Speed Typing 题意概述 给出两个字符串I和P,问能否通过删除P中若干个字符得到I?如果能的话,需要删除字符的个数是多少? 数据规模 \[1≤|I|,|P|≤10^5 \] 双指针 设置两个 ...

  4. 2017 google Round C APAC Test 题解

    题解参考网上的答案,以及我自己的想法. 主要参考网站:http://codeforces.com/blog/entry/47181,http://codeforces.com/blog/entry/4 ...

  5. google Kickstart Round G 2017 三道题题解

    A题:给定A,N,P,计算A的N!次幂对P取模的结果. 数据范围: T次测试,1 ≤ T ≤ 100 1<=A,N,P<=105 快速幂一下就好了.O(nlogn). AC代码: #inc ...

  6. [leetcode/lintcode 题解] Google面试题:合法组合

    给一个单词s,和一个字符串集合str.这个单词每次去掉一个字母,直到剩下最后一个字母.求验证是否存在一种删除的顺序,这个顺序下所有的单词都在str中.例如单词是’abc’,字符串集合是{‘a’,’ab ...

  7. 【题解】Fuzzy Google Suggest(UVA1462)

    题目链接 题意 给定一个字符串集合,有n次搜索,每次有一个整数x和一个字符串,表示可以对字符串进行x次修改, 包括增加.修改和删除一个字符,问修改后的字符串可能是字符集中多少个字符串的前缀. 思路 简 ...

  8. Google Code Jam 2015 Round1A 题解

    快一年没有做题了, 今天跟了一下 GCJ Round 1A的题目, 感觉难度偏简单了, 很快搞定了第一题, 第二题二分稍微考了一下, 还剩下一个多小时, 没仔细想第三题, 以为 前两个题目差不多可以晋 ...

  9. Google Code Jam 2014 Qualification 题解

    拿下 ABD, 顺利晋级, 预赛的时候C没有仔细想,推荐C题,一个非常不错的构造题目! A Magic Trick 简单的题目来取得集合的交并 1: #include <iostream> ...

随机推荐

  1. requests.get()解析

    1.requests.get(url, params=None, headers=None, cookies=None, auth=None, timeout=None) Sends a GET re ...

  2. Maven仓库 - 分发构件至远程仓库

    分发构件至远程仓库   mvn install 会将项目生成的构件安装到本地Maven仓库,mvn deploy 用来将项目生成的构件分发到远程Maven仓库.本地Maven仓库的构件只能供当前用户使 ...

  3. Python构建web应用(进阶版)->对网页HTML优化逻辑显示

    本篇是承接上一篇web应用(入门级)的内容往下顺延的,阅读后将会了解HTML逻辑显示优化,如下图所示,从杂乱无章的日志文件到一个整齐的列表显示. —————————————————————————— ...

  4. 小强版之无码理解C语言指针

     1. 先从普通变量开始   2. 撸完变量撸指针   3. 故事情节进一步发展,此处少儿不宜   4. 奶茶妹妹捉奸,小强死定了   5. 源码欣赏  #include <stdio.h> ...

  5. ClassLoader.loadClass()与Class.forName()的区别

    ClassLoader.loadClass()与Class.forName()都是反射用来构造类的方法,但是他们的用法还是有一定区别的. 在讲区别之前,我觉得很有不要把类的加载过程在此整理一下. 在J ...

  6. 我对BP网络的简单的理解

    最近在学习tf的神经网络算法,十多年没有学习过数学了,本来高中数学的基础,已经彻底还给数学老师了.所以我把各种函数.公式和推导当做黑盒子来用,理解他们能做到什么效果,至于他们是如何做到的,暂时不去深究 ...

  7. 卸载CentOS7自带的OpenJDK

    http://blog.csdn.net/xiegh2014/article/details/52343438

  8. 感谢Thunder

    感谢Thunder团队中的每一位成员. 组长王航认真负责,是一个合格优秀的领导者与伙伴,老师布置的任务都会及时分配给每个人,对待每一项任务都认真严谨负责,了解每个成员的优势及强项. 成员李传康.宋雨. ...

  9. java 面试 -- 4

    Java面试知识点总结   本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有 ...

  10. bug排查

    有时候让朋友,或者群友,或者同事帮忙看一样困扰你很久的bug会得到意向不到的结果. 因为他们往往不像你,已经在调试代码的过程中被一些东西给束缚了.他们会凭借自己的第一直觉来尝试解决问题,跳过你已经走的 ...