三分法Easy Problem

Easy Problem

时间限制:1000 ms  |  内存限制:65536 KB
描述

In this problem, you're to calculate the distance between a point P(xpypzp) and a segment (x1y1z1) − (x2,y2z2), in a 3D space, i.e. the minimal distance from P to any point Q(xqyqzq) on the segment (a segment is part of a line).

输入

The first line contains a single integer T (1 ≤ T ≤ 1000), the number of test cases. Each test case is a single line containing 9 integers xpypzpx1y1z1x2y2z2. These integers are all in [-1000,1000].

输出

For each test case, print the case number and the minimal distance, to two decimal places.

样例输入
3
0 0 0 0 1 0 1 1 0
1 0 0 1 0 1 1 1 0
-1 -1 -1 0 1 0 -1 0 -1
样例输出
Case 1: 1.00
Case 2: 0.71
Case 3: 1.00

不满足单调性,所以不能直接二分查找,三分查找。

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
const double EPS = 1e-8;

struct Node{
	double x;
	double y;
	double z;
};

double Cal(Node p1,Node p2)
{
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z));
}

double Solve(Node p,Node p1,Node p2)
{
	Node mid,midmid;
	Node left = p1,right = p2;
	double mid_len,midmid_len;
	while(Cal(left,right)>EPS)
	{
		mid.x = (left.x + right.x) / 2.0;
		mid.y = (left.y + right.y) / 2.0;
		mid.z = (left.z + right.z) / 2.0;
		midmid.x = (mid.x + right.x) / 2.0;
		midmid.y = (mid.y + right.y) / 2.0;
		midmid.z = (mid.z + right.z) / 2.0;
		mid_len = Cal(p, mid);
		midmid_len = Cal(p, midmid);
		if (mid_len <= midmid_len)
			right = midmid;
		else
			left = mid;
	}
	return Cal(p,left);
}

int main()
{
	freopen("in.txt","r",stdin);
	int count = 1;
	int t;
	cin>>t;
	Node p,l,r;
	while(t--)
	{	
		cin>>p.x>>p.y>>p.z;
		cin>>l.x>>l.y>>l.z;
		cin>>r.x>>r.y>>r.z;
		printf("Case %d: %.2lf\n",count++,Solve(p,l,r));
	}
}


原文地址:https://www.cnblogs.com/lgh1992314/p/5835348.html