首页 > 试题广场 >

绕距

[编程题]绕距
  • 热度指数:48580 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}在城市道路规划中,绕距是一个很重要的概念,指的是城市中两个重要人员聚集点之间的欧几里得距离(欧氏距离)与曼哈顿距离之差的绝对值。一般而言,绕距越小,则城市交通参与者在这两个地点之间所走的“冤枉路”就越小。

\hspace{15pt}欧几里得距离(Euclidean distance)表示两点间的直线距离;曼哈顿距离(Manhattan distance)表示只沿着横平竖直的城市街道从起点到达终点的最短距离。

\displaystyle d_E = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}

\displaystyle d_M = |x_1 - x_2| + |y_1 - y_2|

\hspace{15pt}定义两点间的绕距为

\displaystyle \Delta = \bigl|d_M - d_E\bigr|

输入描述:
\hspace{15pt}第一行输入两个整数 x_1,y_1-10^4 \leqq x_1,y_1 \leqq 10^4),分别表示起点的横坐标和纵坐标。

\hspace{15pt}第二行输入两个整数 x_2,y_2-10^4 \leqq x_2,y_2 \leqq 10^4),分别表示终点的横坐标和纵坐标。


输出描述:
\hspace{15pt}输出一个实数,表示两点之间的绕距 \Delta。注意,由于浮点数存在误差,只要您的答案与标准答案之间的误差不超过 10^{-6},您的答案就会被认为是正确的。
示例1

输入

0 0
1 1

输出

0.585786437626904951

说明

两点间曼哈顿距离为 2,欧几里得距离为 \sqrt{2},结果为 2- \sqrt{2},约为 0.585786437626904951
x1,y1 = map(int,(input().split()))
x2,y2 = map(int,(input().split()))
de = ((x1-x2)**2 + (y1-y2)**2)**0.5
dm = abs(x1-x2) + abs(y1-y2)
print(abs(dm - de))
发表于 2025-06-29 16:17:06 回复(0)
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
int main() {
    double x1, y1;
    cin >> x1 >> y1;
    double x2, y2;
    cin >> x2 >> y2;
    double de = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
    double dm = fabs(x1 - x2) + fabs(y1 - y2);
    cout << fixed << setprecision(18) << fabs(dm - de) << endl;
}
发表于 2025-09-08 17:28:25 回复(0)
from decimal import Decimal, getcontext 
getcontext().prec=50
x1,y1=map(int,input().split())
x2,y2=map(int,input().split())
dx=abs(x1-x2)
dy=abs(y1-y2)
dm=Decimal(f"{dx+dy}")
de=Decimal(f"{dx**2+dy**2}")**Decimal('0.5')
dd=f"{abs(dm-de)}"
if '.' in dd:
    l,r=dd.split('.')
    result=f"{l}.{r[:18].ljust(18,'0')}"
else:
    result=f"{dd}.{'0'*18}"
print(result)

发表于 2025-10-22 17:55:19 回复(0)
import math
t1=input()
t2=input()
x1,y1=t1.split()
x2,y2=t2.split()
de=math.sqrt((int(x1)-int(x2))**2+(int(y1)-int(y2))**2)
dm=abs(int(x1)-int(x2))+abs(int(y1)-int(y2))
t=abs(dm-de)
print(t)

发表于 2025-07-19 16:11:08 回复(0)
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    int x1,x2,y1,y2,b,c;
    cin>>x1>>y1;
    cin>>x2>>y2;
    b=(x1-x2)*(x1-x2);c=(y1-y2)*(y1-y2);
    double E;double M;
    E=sqrt(b+c);
    M=abs(x1-x2)+abs(y1-y2);
    double T;
    T=abs(M-E);
    cout<<fixed <<setprecision(18)<<T;
}
// 64 位输出请用 printf("%lld")
//可以帮忙指出还有哪里可以优化

发表于 2026-05-03 17:49:38 回复(0)
#include<stdio.h>
#include<math.h>
int main()
{
    int x1,y1,x2,y2;
    scanf("%d %d",&x1,&y1);
    scanf("%d %d",&x2,&y2);
    double e=sqrt((x1-x2)*(x1-x2)+((y1-y2)*(y1-y2)));
    double m=sqrt((x1-x2)*(x1-x2))+sqrt((y1-y2)*(y1-y2));
    double l=sqrt((m-e)*(m-e));
    printf("%lf",l);
    return 0;
}
发表于 2026-02-22 11:48:08 回复(0)
#include <iostream>
using namespace std;
#include <cmath>
#include <iomanip>


int main(){
    double x1,y1;
    double x2,y2;
    cin >> x1 >> y1 >> x2 >> y2;
    double dE = sqrt(pow(x1-x2,2) + pow(y1-y2,2));
    double dM = std::abs(x1-x2) + std::abs(y1-y2);
    double c = std::abs(dE - dM);
    cout << fixed << setprecision(18);
    cout << c << endl;
    return 0;
}


发表于 2025-12-07 02:44:19 回复(0)
import math
a,b  =  map(int,input().split())
c,d  =  map(int,input().split())
M_distance = abs(c-a)+abs(b-d)
O_distance = math.sqrt(pow(c-a,2)+pow(b-d,2))
print(M_distance-O_distance)
发表于 2025-10-28 18:41:59 回复(0)
/*2025年10月12日00:49:03
输出一个实数,表示两点之间的绕距
Δ
Δ。注意,由于浮点数存在误差,只要您的答案与标准答案之间的误差不超过10−6,您的答案就会被认为是正确的。*/

# include <stdio.h>
# include <math.h>//包含数学函数的头文件

int main()
{
	int x1, y1, x2, y2;
	double dE, dM, data;

	scanf("%d %d\n", &x1, &y1);
	scanf("%d %d", &x2, &y2);

	dE = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
	//pow() 是 C 标准库 <math.h> 中的一个函数,用于计算一个数的幂。
	// 具体来说,它返回的是第一个参数的第二个参数次幂,即 x^ y。

	dM = (abs(x1 - x2) + abs(y1 - y2));
	//C 库函数 int abs(int x) 返回整数 x 的绝对值。
	//注意:abs() 函数只适用于整数,如果需要计算浮点数的绝对值,需要使用 fabs() 函数。
	
	data = fabs(dM - dE);
	//C 库函数 double fabs(double x) 返回浮点数 x 的绝对值。
	//fabs() 是 C 标准库 <math.h> 中的一个函数,用于计算一个数的绝对值。这个函数在处理数***算时非常有用,可以确保获得数值的非负表示。
	//注意:fabs() 函数可以用于 double、float 和 long double 类型的参数。如果需要计算整数的绝对值,应该使用 abs() 函数。

	printf("%.18f", data);
	return 0;
}

发表于 2025-10-12 01:11:03 回复(0)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            String city1 = in.nextLine();
            String city2 = in.nextLine();
            String [] ab = city1.split(" ");
            String [] cd = city2.split(" ");

            double x = Math.abs(Integer.valueOf(ab[0])-Integer.valueOf(cd[0]));
            double y = Math.abs(Integer.valueOf(ab[1])-Integer.valueOf(cd[1]));
            double E = Math.sqrt(x*x+y*y);
            double M = x + y ;
            double z = Math.abs(M - E);
            System.out.println(z);
        }
    }

发表于 2025-08-27 18:30:04 回复(0)
#include <stdio.h>
#include <math.h>
int main() {
    int x1, y1, x2, y2;
    scanf("%d %d\n", &x1, &y1);
    scanf("%d %d\n", &x2, &y2);
    int x3 = x1 - x2 < 0 ? -(x1 - x2) : x1 - x2;
    int y3 = y1 - y2 < 0 ? -(y1 - y2) : y1 - y2;
    int M = x3 + y3;
    double E = sqrt((x3 * x3) + (y3 * y3));
    double D = M - E < 0 ? -(M - E) : M-E;
    printf("%.6lf", D);
    return 0;
}
发表于 2025-07-06 15:57:13 回复(1)
#include <stdio.h>

double my_abs(double x) {
    return x < 0 ? -x : x;
}//条件操作符。三目操作符 取绝对值

double isqrt(double n) {
    double  x = n;
    double y;
    do {
        y = x;
        x = (x + n / x) / 2.0;
    } while (my_abs(x-y)>1e-12);
       
    return x;
}

int main() {

    int  x1, y1, x2, y2;
    scanf("%d %d", &x1, &y1);
    scanf("%d %d", &x2, &y2);//输入

    double dE = isqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    int  dM = my_abs(x1-x2) + my_abs(y1-y2);

    printf("%lf", my_abs(dM - dE));
   
    return 0;
}
发表于 2026-04-29 13:21:46 回复(0)
import math

x1, y1 = map(int, input().split())
x2, y2 = map(int, input().split())
de = math.sqrt((x1-x2)**2 + (y2-y1)**2)
dm = abs(x2-x1) + abs(y2-y1)
print(abs(dm-de))

发表于 2026-04-23 18:57:29 回复(0)
x1,y1 = map(int, input().split())
x2,y2 = map(int, input().split())
import math
s = abs(math.sqrt(((x1 - x2)**2 + (y1 - y2)**2)) - (abs(x1 - x2) + abs(y1 - y2)))
print(s)
发表于 2026-04-19 13:57:45 回复(0)
import math

x1,y1 = map(int,input().split())
x2,y2 = map(int,input().split())

dE = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
dM = abs(x1 - x2) + abs(y1 -y2)

Delat = abs(dM - dE)
print(Delat)
发表于 2026-04-18 14:09:20 回复(0)
using System;
public class Program {
    public static void Main() {
        string[] inp1 = Console.ReadLine().Split();
        string[] inp2 = Console.ReadLine().Split();
        int x1 = int.Parse(inp1[0]), y1 = int.Parse(inp1[1]), x2 = int.Parse(inp2[0]), y2 = int.Parse(inp2[1]);
        double dE = Math.Sqrt(Math.Pow(x1 - x2, 2)+Math.Pow(y1 - y2, 2));
        double dM = Math.Abs(x1-x2)+ Math.Abs(y1-y2);
        double M = Math.Abs(dM-dE);
        Console.WriteLine(M.ToString("F18"));
    }
}
发表于 2026-04-17 21:24:17 回复(0)
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Scanner;

public class Main {
// 设置一个足够大的精度上下文,比如 50 位,防止中间计算精度丢失
// 最后输出时我们再截取到 18 位
private static final MathContext mc = new MathContext(50, RoundingMode.HALF_UP);

public static void main(String[] args) {
Scanner in = new Scanner(System.in);

while (in.hasNext()) {
// 1. 读取输入
// 即使是整数,我们也当作 BigDecimal 读入,防止转换损失
BigDecimal x1 = in.nextBigDecimal();
BigDecimal y1 = in.nextBigDecimal();
BigDecimal x2 = in.nextBigDecimal();
BigDecimal y2 = in.nextBigDecimal();

// 2. 计算欧几里得距离 E = sqrt((x1-x2)^2 + (y1-y2)^2)
BigDecimal diffX = x1.subtract(x2);
BigDecimal diffY = y1.subtract(y2);

// 计算平方和
BigDecimal sumSq = diffX.multiply(diffX).add(diffY.multiply(diffY));

// 调用自定义的高精度开方方法
BigDecimal E = sqrt(sumSq);

// 3. 计算曼哈顿距离 M = |x1-x2| + |y1-y2|
BigDecimal M = diffX.abs().add(diffY.abs());

// 4. 计算差值 D = M - E
BigDecimal D = M.subtract(E);

// 5. 格式化输出:保留 18 位小数,直接截断 (RoundingMode.DOWN)
System.out.println(D.setScale(18, RoundingMode.DOWN));
}

in.close();
}

/**
* 使用牛顿迭代法计算 BigDecimal 的平方根
* 公式: x(n+1) = 0.5 * (x(n) + num / x(n))
*/
public static BigDecimal sqrt(BigDecimal num) {
if (num.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO;

// 初始猜测值:使用 double 的 sqrt 结果作为起点,这样收敛很快
BigDecimal x = new BigDecimal(Math.sqrt(num.doubleValue()));

// 迭代直到收敛
// 我们设定一个极小的误差范围,或者直接迭代固定次数(因为精度是 50 位,迭代几十次就够了)
BigDecimal lastX = BigDecimal.ZERO;

while (x.compareTo(lastX) != 0) {
lastX = x;
// x = (x + num / x) / 2
x = x.add(num.divide(x, mc)).divide(new BigDecimal("2"), mc);
}

return x;
}
}
发表于 2026-04-09 09:46:33 回复(1)
using System;
public class Program {
    public static void Main() {
             string[] x1_y1 = Console.ReadLine().Split();
        string[] x2_y2 = Console.ReadLine().Split();
        double[] x1_y1_double = Array.ConvertAll(x1_y1, double.Parse);
        double[] x2_y2_double = Array.ConvertAll(x2_y2, double.Parse);
        double dE = Math.Sqrt(Math.Pow((x1_y1_double[0] - x2_y2_double[0]), 2) + Math.Pow((x1_y1_double[1] - x2_y2_double[1]), 2));
        double dM = Math.Abs(x1_y1_double[0] - x2_y2_double[0]) + Math.Abs(x1_y1_double[1] - x2_y2_double[1]);
        Console.WriteLine(dM-dE);
    }
}
发表于 2026-04-08 18:08:46 回复(0)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main() {

    int x1,y1,x2,y2;
    scanf("%d %d\n",&x1,&y1);
    scanf("%d %d",&x2,&y2);
    long double n = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    long double m = abs(x1 - x2) + abs(y1 - y2);
    long double v = fabsl(m - n);
    printf("%.18Lf",v);

    return 0;
}

发表于 2026-03-24 15:33:53 回复(0)
import java.util.Scanner;

import java.math.BigDecimal;
import java.math.RoundingMode;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
        Double x1 = in.nextDouble();
        Double y1 = in.nextDouble();
        Double x2 = in.nextDouble();
        Double y2 = in.nextDouble();
        double e = Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
        double m = Math.abs(x1-x2) + Math.abs(y1-y2);
        BigDecimal ans = new BigDecimal(Math.abs(m-e)).setScale(18,RoundingMode.DOWN);
        System.out.println(ans.toPlainString());
        }
    }
}

发表于 2026-03-23 20:17:02 回复(1)