1. 程式人生 > 其它 >Codeforces Beta Round #2 C. Commentator problem

Codeforces Beta Round #2 C. Commentator problem

題意

二維平面上,給定三個圓的原點和半徑,求一個點到三個圓的視角相同。
三個圓心不共線。

思路

用(距離/半徑)表示視角大小,用方差表示視角的波動。
用爬山演算法從重心開始四個方向爬山。

C#10 .net6程式碼

List<double> x = new();
List<double> y = new();
List<double> r = new();

for (int i = 0; i < 3; i++)
{
	var line = Console.ReadLine()!.Split(' ');
	x.Add(double.Parse(line[0]));
	y.Add(double.Parse(line[1]));
	r.Add(double.Parse(line[2]));
}

double xx = x.Sum() / 3;
double yy = y.Sum() / 3;

int[] dx = { 0, 0, -1, 1 };
int[] dy = { -1, 1, 0, 0 };

const double eps = 1e-5;
double t = 1;

double Dist(double x1, double y1, double x2, double y2)
{
	return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

double Gao(double xx, double yy, List<double> x, List<double> y, List<double> r)
{
	List<double> a = new();
	for (int i = 0; i < 3; i++)
	{
		a.Add(Dist(xx, yy, x[i], y[i]) / r[i]);
	}
	double av = a.Sum() / 3;
	double res = 0;
	for (int i = 0; i < 3; i++)
	{
		res += (a[i] - av) * (a[i] - av);
	}
	return res / 3;
}

while (t > eps)
{
	double cur = Gao(xx, yy, x, y, r);
	bool f = false;
	for (int i = 0; i < 4; i++)
	{
		if (Gao(xx + dx[i] * t, yy + dy[i] * t, x, y, r) < cur)
		{
			xx = xx + dx[i] * t;
			yy = yy + dy[i] * t;
			f = true;
			break;
		}
	}
	if (!f)
	{
		t *= 0.5;
	}
}
if (Gao(xx, yy, x, y, r) < eps)
{
	Console.WriteLine($"{xx} {yy}");
}