zoukankan      html  css  js  c++  java
  • 【bzoj3680】吊打XXX 随机化

    题目描述

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

    输入

    输入第一行为一个正整数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

    输出

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

    样例输入

    3
    0 0 1
    0 2 1
    1 1 1

    样例输出

    0.577 1.000


    题解

    据大爷说可以使用数学算法,蒟蒻不会于是写了随机化爬山算法

    对于某个点,如果合外力不为零,则计算其合外力方向,最终位置一定大致在该点的该方向。

    于是我们可以先随机选择一个点(这里选第一个点)作为初始点,然后使用爬山算法计算即可得到近似最优解。其中计算合外力方向可以使用正交分解法

    注意一下精度什么的就好了。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 10010
    using namespace std;
    int x[N] , y[N] , w[N];
    double dis(double x , double y)
    {
    	return sqrt(x * x + y * y);
    }
    int main()
    {
    	int n , i;
    	double px , py , fx , fy , t;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%d%d%d" , &x[i] , &y[i] , &w[i]);
    	for(px = x[i] , py = y[i] , t = 10000 ; t > 0.0001 ; t *= 0.99)
    	{
    		for(fx = fy = 0 , i = 1 ; i <= n ; i ++ )
    			if(px != x[i] || py != y[i])
    				fx += w[i] * (x[i] - px) / dis(x[i] - px , y[i] - py) , fy += w[i] * (y[i] - py) / dis(x[i] - px , y[i] - py);
    		if(fx || fy)
    			px += t * fx / dis(fx , fy) , py += t * fy / dis(fx , fy);
    	}
    	printf("%.3lf %.3lf
    " , px , py);
    	return 0;
    }
    

     

  • 相关阅读:
    iOS证书的使用
    ios设备管理
    矩阵的相关问题(旋转矩阵&螺旋矩阵)
    flex实现多列布局效果&对角线布局
    peerdependencies
    数组和对象遍历方法对比
    async和defer
    Promise.all并发限制
    electron+react开发属于自己的桌面应用
    webpack代码切割
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7245714.html
Copyright © 2011-2022 走看看