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的正方形,且边与坐标轴平行

 /*
题解: 赛后看到有不少随机化算法可乱搞过去
该题是二维平面邮局距离(参见《算法导论》)的变形 simple版:一维下, 使得Σwi*|X-xi|最小, 其中所有wi = 1. 答案显然为xi的中位数
middle版:我们可以将wi看成有wi个点重合, 权值均为1, 则可套用simple版解法
hard版:二维下, 使得 Σwi*(|X-xi| +|Y-yi|)最小. X轴, Y轴分开解即可
此题:我们将整个平面旋转45°即可变为hard版. 为什么? 因为hard中|X-xi| +|Y-yi|表示的边界形状为以(xi, yi)为中心的45°倾斜的正方形
而本题max(|X-xi|, |Y-yi|)表示的边界形状为以(xi, yi)为中心的正方形
*/ #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <functional>
#include <cmath>
#include <string.h> using namespace std;
using ull = unsigned long long;
using ll = long long;
using db = double;
using PII = pair<int, int>; template<typename T>
void print_vec(T& container, const std::string& sep = " "){
for (auto& x: container){
std::cout << x << sep;
}
std::cout << std::endl;
} template<typename T>
void print_map(T& mp){
for(auto& x: mp){
std::cout << x.first << " " << x.second << std::endl;
}
} struct Point{
double x, y, w;
void input(){
cin >> x >> y >> w;
}
double dist(double _x, double _y){
return fabs(x - _x) + fabs(y - _y);
}
void rotate(){
static double ang = 45.0 / * acos(-1.0);
double x1 = x * cos(ang) - y * sin(ang);
double y1 = x * sin(ang) + y * cos(ang);
x = x1 * sin(ang) ;
y = y1 * sin(ang) ;
}
};
struct Problem{ int N;
Point p[];
void read(){
cin >> N;
for (int i = ; i < N; i++){
p[i].input();
p[i].rotate();
}
} struct WEIGHT{
double w;
double x;
bool operator<(const WEIGHT& wt) const{
return x < wt.x;
}
}; double calc(WEIGHT wt[], int n){
sort(wt, wt + n);
double ans = ;
double cur_x = wt[].x;
double pre_sum = ;
double suf_sum = ;
for (int i = ; i < n; i++){
ans += (wt[i].x - cur_x) * wt[i].w;
suf_sum += wt[i].w;
}
double ret = ans;
for (int i = ; i < n; i++){
double nxt_x = wt[i].x;
suf_sum -= wt[i-].w;
pre_sum += wt[i-].w;
ans -= suf_sum * (nxt_x - cur_x);
ans += pre_sum * (nxt_x - cur_x);
cur_x = nxt_x;
ret = min(ans, ret);
}
return ret;
}
void solve(int ca){
printf("Case #%d: ", ca); WEIGHT vx[], vy[];
for (int i = ; i < N; i++){
vx[i].x = p[i].x;
vx[i].w = p[i].w;
vy[i].x = p[i].y;
vy[i].w = p[i].w;
}
double sum = calc(vx, N) + calc(vy, N);
printf("%.7f\n", sum);
}
}; int main(){
int T;
cin >> T;
for (int ca = ; ca <= T; ca++){
Problem p;
p.read();
p.solve(ca);
}
}

附随机化模拟退火算法:

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <climits>
#include <stack>
#include <queue>
#include <ctime>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std; #define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define MP(a,b) make_pair(a,b) typedef long long ll;
typedef pair<int,int> pii;
const int INF = ( << ) - ;
const int MAXN = ;
const double cof = 0.5;
const double eps = 1e-;
const double deta = 0.7; int T,N;
double X[MAXN],Y[MAXN], W[MAXN];
int dir[][] = {{-,},{,},{,-},{,}}; double Dis(double a1,double b1,double a2,double b2){
return max(abs(a1-a2), abs(b1-b2));
} double Cal(double a,double b){
double res = Dis(a,b,X[],Y[]) * W[];
FOR(i,,N - ) res += Dis(a,b,X[i],Y[i]) * W[i];
return res;
} int main(){
srand((unsigned)time(NULL));
int a,b;
scanf("%d",&T);
FOR(tt,,T){
scanf("%d",&N);
REP(i,N) scanf("%lf%lf%lf",&X[i],&Y[i], &W[i]);
double ans = -,ansx,ansy;
REP(o,){
double sx = rand() % (N + );
double sy = rand() % (N + );
double res = Cal(sx,sy);
double step = N;
while(step > eps){
while(){
bool mov = false;
REP(k,){
double tx = sx + dir[k][] * step;
double ty = sy + dir[k][] * step;
if(tx < - || tx > || ty < - || ty > ) continue;
double tmp = Cal(tx,ty);
if(tmp < res || (double)rand()/INT_MAX > deta){
res = tmp;
sx = tx;
sy = ty;
mov = true;
}
}
if(mov == false) break;
}
step *= cof;
}
if(ans == - || res < ans){
ans = res;
ansx = sx;
ansy = sy;
}
}
printf("Case #%d: %.6lf\n", tt, ans);
//printf("The safest point is (%.1f, %.1f).\n",ansx,ansy);
}
return ;
}

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. python log封装

    # _*_ coding:utf-8 _*_ import logging import os import sys import time log_path = os.path.dirname(sy ...

  2. Controller - 压力机的设置 - 界面图表分析

    一. Controller- 压力机界面的一下设置讲解   2种测试场景的设计和压测策略 二. Controller- 压力机界面的图表分析

  3. FinTech领域实践:乐维监控助力西南某上市城商行IT运维转型升级!

    FinTech领域实践:乐维监控助力西南某上市城商行IT运维转型升级! 项目背景 随着信息化的逐步深入,企业业务运营活动对IT的依赖程度越来越高,传统的局部.粗放.碎片化的IT运维管理模式已经无法满足 ...

  4. python数据分析系列(2)--numpy

    NumPy(Numerical Python的简称)是Python数值计算最重要的基础包.大多数提供科学计算的包都是用NumPy的数组作为构建基础. NumPy的部分功能如下: ndarray,一个具 ...

  5. bitcoin PoW原理及区块创建过程

    bitcoin PoW原理及区块创建过程 PoW 为了在点对点的基础上实现一个分布式时间戳服务器,我们需要使用PoW(Proof of Work)系统来达成共识.PoW过程就是寻找一个目标值的过程,当 ...

  6. Python字典 (dict)

    作者博文地址:http://www.cnblogs.com/spiritman/ 字典是Python语言中唯一的映射类型.字典对象是可变的,它是一个容器类型,支持异构.任意嵌套. 创建字典 语法:{k ...

  7. JavaScript设计模式-----模板方法模式

    模板方法模式是一种只需要使用继承就可以实现的非常简单点的模式. 模板方法模式有两部分组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现 一些公共方法以及 ...

  8. mysql实现oracle sequence方案

    转自: http://blog.csdn.net/javaGirlOne/article/details/47256183 背景:先总结一下MYSQL 自增长与ORACLE 序列的区别: 自增长只能用 ...

  9. 实验五 Java网络编程及安全 实验报告 20135232王玥

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序与设计         班级:1352 姓名:王玥 学号:20135232 成绩:             指导 ...

  10. bata6

    目录 组员情况 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内最新成果 团队签入记 ...