模拟退火 BZOJ-3680

来源:互联网 发布:php格式视频怎么打开 编辑:程序博客网 时间:2024/06/08 16:25

大家都很强,可与之共勉。

LINK

Description

gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty。gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了。蒟蒻们将
n个gty吊在n根绳子上,每根绳子穿过天台的一个洞。这n根绳子有一个公共的绳结x。吊好gty后蒟蒻们发现由于每个gty重力不同,绳
结x在移动。蒟蒻wangxz脑洞大开的决定计算出x最后停留处的坐标,由于他太弱了决定向你求助。
不计摩擦,不计能量损失,由于gty足够矮所以不会掉到地上。

Input

输入第一行为一个正整数n(1<=n<=10000),表示gty的数目。
接下来n行,每行三个整数xi,yi,wi,表示第i个gty的横坐标,纵坐标和重力。
对于20%的数据,gty排列成一条直线。
对于50%的数据,1<=n<=1000。
对于100%的数据,1<=n<=10000,-100000<=xi,yi<=100000

Output

输出1行两个浮点数(保留到小数点后3位),表示最终x的横、纵坐标。

Sample Input

3

0 0 1

0 2 1

1 1 1

Sample Output

0.577 1.000

题解
自己写的模拟退火好慢啊
思路就是先随机几个点,再同时更新这几个点,顺便维护答案。

/**************************************************************    Problem: 3680    User: Lazer2001    Language: C++    Result: Accepted    Time:9840 ms    Memory:1528 kb****************************************************************/# include <bits/stdc++.h>const double eps = 1e-5 ;inline short epssgn ( const double& x )  {    return ( x > -eps ) - ( x < eps ) ;}struct Point  {    double x, y ;} buf [5] ;struct GTY  {    double x, y, w ;    inline void Init ( )  {        scanf ( "%lf%lf%lf", & x, & y, & w ) ;    }} a [10010] ;int n ;inline double frand ( )  {    return ( rand ( ) & 1 ) ? ( rand ( ) % 101 ) * 1.0 : - ( rand ( ) % 101 ) * 1.0 ;}inline double Dis ( Point& a, const Point& b )  {    double t1 = a.x - b.x, t2 = a.y - b.y ;    return sqrt ( t1 * t1 + t2 * t2 ) ; }inline double Cal ( Point& p )  {    double ret ( 0 ) ;    for ( register int i = 1 ; i <= n ; ++ i )  ret += a [i].w * Dis ( p, ( Point ) { a [i].x, a [i].y  } ) ;    return ret ;}inline Point SA (  )  {    double temprature = 100.0 ;    const double delta = 0.97 ;    Point ans ;    register bool flag ;    register double tmp ;    while ( temprature > eps )  {        flag = 1 ;        while ( flag )  {            flag = 0 ;            for ( int i = 0 ; i < 5 ; ++ i )  {                double _ret_ = Cal ( buf [i] ) ;                Point QQQ = ( Point ) { buf [i].x + frand ( ) * temprature, buf [i].y + frand ( ) * temprature } ;                if ( epssgn ( QQQ.x + 100000 ) >= 0 && epssgn ( 100000 - QQQ.x ) >= 0 && epssgn ( QQQ.y + 100000 ) >= 0 && epssgn ( 100000 - QQQ.y ) >= 0 )  {                    if ( ( ( tmp = Cal ( QQQ ) ) <= _ret_ ) && ( ans = buf [i] = QQQ, flag = 1 ) ) ;                }            }        }        temprature *= delta ;    }    return ans ;}int main ( )  {    srand ( 20010608 ) ;    scanf ( "%d", & n ) ;    for ( int i = 1 ; i <= n ; ++ i )   a [i].Init ( ) ;    for ( int i = 0 ; i < 5 ; ++ i )    buf [i].x = fabs ( frand ( ) ), buf [i].y = fabs ( frand ( ) ) ;    Point ans = SA ( ) ;    return printf ( "%.3lf %.3lf\n", ans.x, ans.y ), 0 ;}
原创粉丝点击