codeforces 2C Commentator problem
来源:互联网 发布:淘宝快递单模板 编辑:程序博客网 时间:2024/04/28 14:34
The Olympic Games in Bercouver are in full swing now. Here everyone has their own objectives: sportsmen compete for medals, and sport commentators compete for more convenient positions to give a running commentary. Today the main sport events take place at three round stadiums, and the commentator's objective is to choose the best point of observation, that is to say the point from where all the three stadiums can be observed. As all the sport competitions are of the same importance, the stadiums should be observed at the same angle. If the number of points meeting the conditions is more than one, the point with the maximum angle of observation is prefered.
Would you, please, help the famous Berland commentator G. Berniev to find the best point of observation. It should be noted, that the stadiums do not hide each other, the commentator can easily see one stadium through the other.
The input data consists of three lines, each of them describes the position of one stadium. The lines have the format x, y, r, where (x, y) are the coordinates of the stadium's center ( - 103 ≤ x, y ≤ 103), and r (1 ≤ r ≤ 103) is its radius. All the numbers in the input data are integer, stadiums do not have common points, and their centers are not on the same line.
Print the coordinates of the required point with five digits after the decimal point. If there is no answer meeting the conditions, the program shouldn't print anything. The output data should be left blank.
题目大意是有3个圆,求一点a,使点a对三个圆的视角相等(过a做圆的两条切线,此两切线的夹角即为视角)。若有多点视角相等,则取视角最大的点。
设三个圆的半径分别为r1,r2,r3。设点a到三个圆的圆心距离分别为d1,d2,d3。
即目标是2*arcsin(r1/d1) = 2*arcsin(r2/d2) = 2*arcsin(r3/d3)。即r1/d1 = r2/d2 = r3/d3
那么这就是解析几何的问题了,就是列出坐标系,一顿算呗。应该很难算。但是算出公式直接给程序就行了。
看到网上还有一种方法,就是一种随机的算法。
从一个初始的解开始逐步逼近最优解。
当迭代了若干步之后,估值函数的值仍然较大时,则不存在解。
最开始,我取的估值函数cost = fabs(ang1-ang2) + fabs(ang2-ang3) + fabs(ang3-ang1). 其中ang1 ang2 ang3就是用arcsin求出来的。
这样的问题就是可能会带来比较大的误差,因为要计算的arcsin的值可能很小,所以一开始一直都没法AC。
后来我把估值函数cost 取为cost = (d1/r1-d2/r2)^2 + (d2/r2-d3/r3)^2 + (d3/r3-d1/r1)^2,效果就好一些,就AC了。
总而言之呢,这种随机算法的题目就是很蛋疼了。但是在蛋疼的基础上,还是可以采取一些办法去减小误差的。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <stack>#include <map>#include <string>using namespace std;struct pt { double x; double y; double r;};pt mkp(double x, double y) { pt ret; ret.x = x; ret.y = y; return ret;}double dis(pt a, pt b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}double cost(pt *p, double x, double y) { double ang[3]; for (int i = 0; i < 3; i++) ang[i] = dis(p[i], mkp(x, y)) / p[i].r; double diff[3]; for (int i = 0; i < 3; i++) diff[i] = ang[i] - ang[(i+1)%3]; double ret = 0; for (int i = 0; i < 3; i++) ret += diff[i] * diff[i]; return ret;}const int dx[] = {0, 1, -1, 0};const int dy[] = {1, 0, 0, -1};const double err = 1e-6;int main() { pt p[3]; for (int i = 0; i < 3; i++) scanf("%lf %lf %lf", &(p[i].x), &(p[i].y), &(p[i].r)); pt ans; ans.x = (p[0].x + p[1].x + p[2].x) / 3.0; ans.y = (p[0].y + p[1].y + p[2].y) / 3.0; double ncost = cost(p, ans.x, ans.y); pt tmp; double step = 1.0; bool flag = false; for (int i = 0; i < 300000 && ncost > err; i++) { flag = false; for (int k = 0; k < 4; k++) { tmp.x = ans.x + step * ((double)dx[k]); tmp.y = ans.y + step * ((double)dy[k]); if (ncost > cost(p, tmp.x, tmp.y)) { ncost = cost(p, tmp.x, tmp.y); ans = tmp; flag = true; } } if (!flag) step *= 0.5; } if (cost(p, ans.x, ans.y) <= err) printf("%.5lf %.5lf\n", ans.x, ans.y); return 0;}
- codeforces 2C Commentator problem
- codeforces 2C Commentator problem
- Codeforces 2C Commentator problem
- [Codeforces]C. Commentator problem
- codeforces 2C Commentator problem (1)-- 几何
- Codeforces Beta Round #2 C. Commentator problem
- Codeforces-2C Commentator problem(随机算法)
- codeforces 2C Commentator problem (2) -- 模拟退火
- Codeforces Beta Round #2 2C Commentator problem(模拟退火)
- codeforces 2 C. Commentator problem(模拟退火)
- CF 2 C. Commentator problem
- CF 2C Commentator problem
- 2C. Commentator problem【模拟退火(枚举)】
- C. Commentator problem (模拟退火)
- 【Codeforces Beta Round 2C】【计算几何 转化 模拟退火】Commentator problem 求一个点,使得该点到三个圆的视角范围尽可能接近
- Commentator problem(爬山)
- Codeforces Round #137 (Div. 2), problem: (C)
- Codeforces Round #173 (Div. 2) Problem C
- float布局问题汇总
- 利用位运算处理权限分配来优化数据库存储,并且提高运算效率
- 兔子生兔子问题
- node.js之express4.x使用命令创建一个ejs项目及常用命令
- Phonegap修改全屏/非全屏设置 Html5
- codeforces 2C Commentator problem
- 第八讲 MFC的进程和线程
- linux的poll机制
- handlerThread
- 面向对象编程中的聚合与耦合
- 跑了OrzNet的Demo
- 「LSI创新亚洲峰会」 个人总结
- MySQL引擎
- 递归算法详细分析