zoukankan      html  css  js  c++  java
  • 【转】【计算几何 转化 模拟退火】求一个点,使得该点到三个圆的视角范围尽可能接近

    转自:http://blog.csdn.net/snowy_smile/article/details/50131317

    C. Commentator problem
    time limit per test
     1 second
    memory limit per test
     64 megabytes
    input
     standard input
    output
     standard output

    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.

    Input

    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.

    Output

    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.

    Sample test(s)
    input
    0 0 10
    60 0 10
    30 30 10
    
    output
    30.00000 0.00000
    
      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<ctype.h>
      4 #include<math.h>
      5 #include<iostream>
      6 #include<string>
      7 #include<set>
      8 #include<map>
      9 #include<vector>
     10 #include<queue>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<time.h>
     14 using namespace std;
     15 void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
     16 #define MS(x,y) memset(x,y,sizeof(x))
     17 #define MC(x,y) memcpy(x,y,sizeof(x))
     18 #define MP(x,y) make_pair(x,y)
     19 #define ls o<<1
     20 #define rs o<<1|1
     21 typedef long long LL;
     22 typedef unsigned long long UL;
     23 typedef unsigned int UI;
     24 template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
     25 template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
     26 const int N=0,M=0,Z=1e9+7,ms63=1061109567;
     27 struct Circle
     28 {
     29     double x,y,r;
     30 }c[3];
     31 double ang[3];
     32 const int dy[4]={-1,0,0,1};
     33 const int dx[4]={0,-1,1,0};
     34 double K(double x)
     35 {
     36     return x*x;
     37 }
     38 double Dis(double x,double y,double xx,double yy)
     39 {
     40     return sqrt(K(x-xx)+K(y-yy));
     41 }
     42 double Val(double x,double y)
     43 {
     44     for(int i=0;i<3;++i)ang[i]=Dis(x,y,c[i].x,c[i].y)/c[i].r;
     45     double val=0;
     46     for(int i=0;i<3;++i)val+=K(ang[i]-ang[(i+1)%3]);
     47     return val;
     48 }
     49 int main()
     50 {
     51     double x=0,y=0;
     52     for(int i=0;i<3;++i)
     53     {
     54         scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);
     55         x+=c[i].x/3;y+=c[i].y/3;
     56     }
     57     double err=Val(x,y);
     58     double step=1;
     59     for(int tim=1;tim<=1e5;++tim)
     60     {
     61         bool flag=0;
     62         double X,Y;
     63         for(int i=0;i<4;++i)
     64         {
     65             double xx=x+dx[i]*step,yy=y+dy[i]*step;
     66             double val=Val(xx,yy);
     67             if(val<err)
     68             {
     69                 err=val;
     70                 flag=1;
     71                 X=xx;Y=yy;
     72             }
     73         }
     74         if(flag){x=X;y=Y;}
     75         else step/=2;
     76     }
     77     if(err<1e-6)printf("%.5f %.5f
    ",x,y);
     78     return 0;
     79 }
     80 /*
     81 【trick&&吐槽】
     82 啦啦啦!
     83 
     84 【题意】
     85 给你三个圆,让你找到一个点,使得从这个点出发,看三个圆的视角范围的角度都一样。
     86 如果有多个满足要求的点,我们希望找到一个点,使得这个视角范围的角度尽可能大。
     87 (如果无解就不输出)
     88 
     89 【类型】
     90 计算几何公式求解or模拟退火
     91 
     92 【分析】
     93 这题可以直接解方程,用计算几何的方法做。
     94 然而最好的,最值得学习有推广价值的算法还是——模拟退火。
     95 
     96 什么是模拟退火呢?以后我们可以再慢慢具体学习。(才不是因为我现在不会啦~  T_T )
     97 按照这道题的学习,大体上是这样做——
     98 bas,设计估价函数
     99 1,初始找一个近似最优解,
    100 2,然后在最优解的四周寻求更优解。这里要保证步长不要太小,否则可能陷入局部最优解。
    101 3,重复步骤2,适当调整步长,继续寻找最优解,直到达到精度要求。
    102 
    103 在这道题上——
    104 估价函数要先求出(距离/半径),这个数值和视角大小有相应的一一对应关系。
    105     然后求出三个圆pair的(距离/半径)的差值的平方和,作为估价函数。
    106     这个值越小,越接近零,显然对于三个圆的视角越接近。
    107 1是重心
    108 2初始为1,找得到更优就继续走。找不到更优就步长缩半
    109 3直到一定的次数或一定的精度
    110 然后这道题就做完啦!做完啦!做完啦!
    111 以后再来加深学习模拟退火哦~~!
    112 
    113 ====================================================================
    114 当然这题有解方程做法啦。因为满足要求的点数其实一筛就没几个了哦~以后再补!
    115 
    116 【时间复杂度&&优化】
    117 O(模拟退火次数)
    118 
    119 */
  • 相关阅读:
    线程高级应用-心得2-同步锁讲解及面试题案例分析
    线程高级应用-心得1-传统线程和定时器讲解及案例分析
    Map拷贝 关于对象深拷贝 浅拷贝的问题
    HashMap对象的深层克隆
    java Collections.sort()实现List排序自定义方法
    java中观察者模式Observable和Observer
    mysql字符串函数(转载)
    CSS的三种样式表和优先级
    Android之微信支付
    Android之扫描二维码和根据输入信息生成名片二维码
  • 原文地址:https://www.cnblogs.com/shizhh/p/5845758.html
Copyright © 2011-2022 走看看