题目链接

https://codeforces.com/contest/685/problem/C

题解

我怎么又还差最后一步的时候放弃了然后往别的方向上想了一小时才发现这个思路能做……

首先二分答案,转化为所有点半径为\(mid\)的曼哈顿距离区域内是否有交。
考虑二维问题,显然可以用曼哈顿转切比雪夫来做,把\((x,y)\)变成\((x+y,x-y)\)那么原来两点的曼哈顿距离就等于后来两点的切比雪夫距离。考虑一下这个做法的证明: \[|x_1-x_2|+|y_1-y_2|=\max(x_1-x_2+y_1-y_2,x_1-x_2-y_1+y_2,-x_1+x_2+y_1-y_2,-x_1+x_2-y_1+y_2)=\max(|(x_1+y_1)-(x_2+y_2)|,|(x_1-y_1)-(x_2-y_2)|)\]
三维的问题也可以用类似的思路。\[|x_1-x_2|+|y_1-y_2|+|z_1-z_2|=\max(|(x_1+y_1+z_1)-(x_2+y_2+z_2)|,|(x_1-y_1+z_1)-(x_2-y_2+z_2)|,|(x_1+y_1-z_1)-(x_2+y_2-z_2)|,|(x_1-y_1-z_1)-(x_2-y_2-z_2)|)\]于是我们可以把\((x,y,z)\)变成一个四维的坐标\((x+y+z,x-y+z,x+y-z,x-y-z)\), 曼哈顿距离就变成了切比雪夫距离,求一下区间交就行了。但是有以下两个附加限制:

(1) 新的坐标\((x,y,z,w)\)必须满足\(w=y+z-x\).

(2) 由于题目里要求所有坐标都是整数,新的坐标\((x,y,z,w)\)必须满足\(y-x,z-x\)都是\(2\)的倍数。
那么可以枚举\(x,y,z,w\)都是奇数或偶数的情况,分别求一下在\(x,y,z\)取值范围内\(y+z-x\)的最大最小值,然后和\(w\)的取值范围求交,调整一下即可求解。
时间复杂度\(O(n\log C)\), \(C\)为值域。

代码

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define riterator reverse_iterator
using namespace std;inline int read()
{int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f;
}const int N = 1e5;
const llong INF = 6e18+1;
struct Point
{llong x,y,z,w;
} a[N+3];
int n;llong fun(llong x,llong y,llong z) {return x&1?x+z:x+y;}bool check(llong mid,bool typ=false)
{llong lx = -INF,ly = -INF,lz = -INF,lw = -INF,rx = INF,ry = INF,rz = INF,rw = INF;for(int i=1; i<=n; i++){lx = max(lx,a[i].x-mid); rx = min(rx,a[i].x+mid);ly = max(ly,a[i].y-mid); ry = min(ry,a[i].y+mid);lz = max(lz,a[i].z-mid); rz = min(rz,a[i].z+mid);lw = max(lw,a[i].w-mid); rw = min(rw,a[i].w+mid);}if(lx>rx||ly>ry||lz>rz||lw>rw) return false;llong lx2 = fun(lx,0,1),ly2 = fun(ly,0,1),lz2 = fun(lz,0,1),lw2 = fun(lw,0,1),rx2 = fun(rx,0,-1),ry2 = fun(ry,0,-1),rz2 = fun(rz,0,-1),rw2 = fun(rw,0,-1);if(lx2<=rx2&&ly2<=ry2&&lz2<=rz2&&lw2<=rw2){llong lw3 = ly2+lz2-rx2,rw3 = ry2+rz2-lx2;if(max(lw2,lw3)<=min(rw2,rw3)){llong w = max(lw2,lw3),x = rx2,y = ly2,z = lz2;if(typ){if(y+z-x<w) {y += min(ry2-ly2,w-(y+z-x));}if(y+z-x<w) {z += min(rz2-lz2,w-(y+z-x));}if(y+z-x<w) {x -= min(rx2-lx2,w-(y+z-x));}llong xx = (y+z)/2ll,yy = (x-y)/2ll,zz = (x-z)/2ll;printf("%I64d %I64d %I64d\n",xx,yy,zz);}return true;}}lx2 = fun(lx,1,0),ly2 = fun(ly,1,0),lz2 = fun(lz,1,0),lw2 = fun(lw,1,0),rx2 = fun(rx,-1,0),ry2 = fun(ry,-1,0),rz2 = fun(rz,-1,0),rw2 = fun(rw,-1,0);if(lx2<=rx2&&ly2<=ry2&&lz2<=rz2&&lw2<=rw2){llong lw3 = ly2+lz2-rx2,rw3 = ry2+rz2-lx2;if(max(lw2,lw3)<=min(rw2,rw3)){if(typ){llong w = max(lw2,lw3),x = rx2,y = ly2,z = lz2;if(y+z-x<w) {y += min(ry2-ly2,w-(y+z-x));}if(y+z-x<w) {z += min(rz2-lz2,w-(y+z-x));}if(y+z-x<w) {x -= min(rx2-lx2,w-(y+z-x));}llong xx = (y+z)/2ll,yy = (x-y)/2ll,zz = (x-z)/2ll;printf("%I64d %I64d %I64d\n",xx,yy,zz);}return true;}}return false;
}int main()
{int T; scanf("%d",&T);while(T--){scanf("%d",&n);for(int i=1; i<=n; i++){llong x,y,z; scanf("%I64d%I64d%I64d",&x,&y,&z);a[i].x = x+y+z,a[i].y = x-y+z,a[i].z = x+y-z,a[i].w = x-y-z;}llong left = 0ll,right = 3e18;while(left<right){llong mid = left+(right-left>>1);if(check(mid)) {right = mid;}else {left = mid+1;}}
//      printf("ans=%I64d\n",right);check(right,true);}return 0;
}

Codeforces 685C Optimal Point (二分、不同类型距离的相互转换)相关推荐

  1. Voltage Keepsake CodeForces - 801C (思维+二分)

    题目链接 这是一道很棒的二分题. 思路: 首先先思考什么情况下是可以无限的使用,即输出-1. 我们思考可知,如果每一秒内所有设备的用电量总和小于等于充电器每秒可以充的电,那么这一群设备就可以无限使用. ...

  2. 经纬度坐标与距离的相互转换及其实现

    经纬度坐标与距离的相互转换 1.经纬度与距离角度的换算关系: 2 Python代码实现 1.经纬度与距离角度的换算关系: a)在纬度相等的情况下: 经度每隔0.00001度,距离相差约1米: 每隔0. ...

  3. JAVA常用类型之间的相互转换

    JAVA常用类型之间的相互转换 String与int String与float String与double hexString与byte数组 json与map JSONArray与List<'m ...

  4. poj 2112 Optimal Milking(二分+Floyd+最大流)

    题意:K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用:并告诉了产奶机.奶牛之间的两两距离Dij(0<=i,j<K+C). 问题:如何安排使得在任何一头奶牛都有自己产奶机的条件下,奶牛 ...

  5. CodeForces - 1538G Gift Set(二分)

    题目链接:点击查看 题目大意:给出 a,b,x,ya,b,x,ya,b,x,y,分别表示有 aaa 个蓝色糖果和 bbb 和红色糖果,现在有两种打包方式: xxx 个蓝色糖果和 yyy 个红色糖果 y ...

  6. POJ - 2112 Optimal Milking(二分+二分图最大匹配-多重匹配(修改匈牙利实现)+Floyd求最短路)

    题目链接:点击查看 题目大意:给出n个牛奶机器,再给出m只奶牛,每个机器只能让最多k只牛一起挤奶,现在问如何分配奶牛,能让最远的那只奶牛到达机器的距离最小 题目分析:很综合的一道题目了,不算很难,但比 ...

  7. Success Rate CodeForces - 807C (数学+二分)

    You are an experienced Codeforces user. Today you found out that during your activity on Codeforces ...

  8. Codeforces - 706B - Interesting drink - 二分 - 简单dp

    https://codeforces.com/problemset/problem/706/B 因为没有看见 $x_i$ 的上限是 $10^5$ ,就用了二分去做,实际上这道题因为可乐的价格上限是 $ ...

  9. CodeForces - 801C Voltage Keepsake 二分

    You have n devices that you want to use simultaneously. The i-th device uses ai units of power per s ...

最新文章

  1. MySQL 误操作恢复表
  2. 报错-Unknown class in Interface Builder file
  3. word受权限保护无法打开_双击文档无法打开到底是啥毛病?简单一招解决
  4. 爬有道翻译的几种方法
  5. leetcode最小面积_LeetCode—— 939. 最小面积矩形(JavaScript)
  6. P1315,jzoj3029-观光公交【费用流】
  7. 【Linux网络编程学习】I/O多路复用——epoll
  8. linux数据库实例开机启动,linux下数据库实例开机自启动设置
  9. python实现8大排序算法
  10. 向服务器上传本地大文件的方法xshell
  11. 计算机专业答辩开场白,毕业答辩开场白三分钟
  12. git push 一直 Incorrect username or password ( access token ) fatal: Authenticatio
  13. Bailian2690 首字母大写【字符串】
  14. java和javascript双引号嵌套的问题
  15. Ajax实现页面自动刷新实例解析
  16. 为什么要玩FLTK(Fast Light Tool Kit)
  17. 【gazebo要素9】 SDF制作Model文件(2)
  18. 苹果库乐队怎么玩_苹果手机使用技巧(例iPhone11)
  19. Mac OS 内存管理知识
  20. 开平方算法的C++实现

热门文章

  1. 北理工 管理系统计算机仿真作业,20秋北理工《CADCAM原理与应用》--模拟3-答案 更…...
  2. easyexcel根据模板写入_ProxmoxVE 之 创建win10基础镜像模板
  3. 形变立体跟踪-基于稠密运动估计和力学仿真(1)
  4. 3DSlicer6:编译、调试、规范化的开发
  5. 最小二乘抛物线拟合原理及证明
  6. 用syslinux启动u盘
  7. 为什么说多道程序概念得到了中断和通道技术的支持?
  8. 【CyberSecurityLearning 36】靶场环境搭建(ubuntu系统安装优化及vulhub安装)
  9. java自定义异常怎么做
  10. QT读取Word文档