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. 使用Serilog输出到ES(使用笔记)

    第一步:安装Serilog 使用NuGet包安装以下组件: Serilog.AspNetCoreSerilog.Settings.ConfigurationSerilog.Sinks.ConsoleS ...

  2. 【LeetCode算法题库】Day7:Remove Nth Node From End of List & Valid Parentheses & Merge Two Lists

    [Q19] Given a linked list, remove the n-th node from the end of list and return its head. Example: G ...

  3. CHAPTER 24 History of Our Planet 第24章 我们行星的历史

    CHAPTER 24 History of Our Planet 第24章 我们行星的历史 Uncovering the bones of ancient beasts is only part of ...

  4. centos7.6 安装 openvpn--2.4.7

    openvpn-server端 搭建 1,软件版本 Centos - 7.x easy-rsa - 3.0.3 OpenVPN - 2.4.7 2,安装 建议安装启用epel源,采用yum的方式安装o ...

  5. 01-numpy基础简介

    import numpy as np # ndarray ''' # 三种创建方式 1.从python的基础数据对象转化 2.通过numpy内置的函数生成 3.从硬盘(文件)读取数据 ''' # 创建 ...

  6. maven摘除jar包中配置文件

    <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-p ...

  7. sprint2(第九天)

    今天是sprint2的最后一天,已经完成功能有可以实现点餐功能.菜品的添加和删减.菜品数量的增减.添加备注.查看订单详情.订单状态.提交订单.后厨可以查看订单信息,对菜品的状态进行操作,是否完成烹饪, ...

  8. 为什么你学过Java却忘光了——记第一次助教同学见面会

    大约两周之前,主讲老师刘志勇老师和我约定,让我上周四到课堂上和同学们认识.交流一下.一开始我不太明了去和大家见面要说些什么,也不太理解这么做的必要性是什么.但随着日子临近,我请教了周筠老师,周筠老师和 ...

  9. “吃神么,买神么”的第一个Sprint计划(第五天)

    “吃神么,买神么”项目Sprint计划 ——5.25  星期一(第五天)立会内容与进度 摘要:logo2出来了,修改过不一样的风格,组内总体评价可以,但是颜色要改,色调没注意,统一决定改成与背景色一致 ...

  10. Spring下使用开发webservice

    依赖包 <!-- CXF Dependencies --> <dependency> <groupId>org.apache.cxf</groupId> ...