zoukankan      html  css  js  c++  java
  • [JSOI2004]平衡点

    题目:洛谷P1337。

    题目大意:
    有n个重物,每个重物有一个重量w,并且绑在一条绳子上。这些绳子在桌面上打成一个结。问结在哪里才能使重物平衡。
    解题思路:
    题意就是要求(sumlimits_{i=1}^n d_i imes w_i)最小((d_i)为重物i到结的距离)。
    模拟退火即可。

    C++ Code:

    #include<bits/stdc++.h>
    #define eps 1e-15
    #define delta 0.991
    struct things{
    	int x,y,w;
    }p[1005];
    struct Answer{
    	double x,y,w;
    }ans,start,now;
    int n,xxx=0,yyy=0;
    inline int readint(){
    	int d=0,c=getchar(),f=0;
    	for(;!isdigit(c);c=getchar())f=c=='-';
    	for(;isdigit(c);c=getchar())d=(d<<3)+(d<<1)+(c^'0');
    	return f?-d:d;
    }
    inline double calc(const double xx,const double yy){
    	double r=0;
    	for(int i=1;i<=n;++i){
    		double x=p[i].x-xx,y=p[i].y-yy;
    		r+=sqrt(x*x+y*y)*p[i].w;
    	}
    	return r;
    }
    int main(){
    	n=readint();
    	for(int i=1;i<=n;++i){
    		xxx+=(p[i].x=readint()),yyy+=(p[i].y=readint());
    		p[i].w=readint();
    	}
    	ans=start=(Answer){1.*xxx/n,1.*yyy/n,calc(1.*xxx/n,1.*yyy/n)};
    	srand(time(0));
    	for(int T=20;T;--T){
    		now=start;
    		for(double nT=5333;nT>eps;nT*=delta){
    			double nx=now.x+((rand()<<1ll)-RAND_MAX)*nT;
    			double ny=now.y+((rand()<<1ll)-RAND_MAX)*nT;
    			double res=calc(nx,ny);
    			if(res<ans.w)ans=(Answer){nx,ny,res};
    			if(res<now.w||exp((res-now.w)/nT)*RAND_MAX<rand())
    			now=(Answer){nx,ny,res};
    		}
    	}
    	printf("%.3f %.3f
    ",ans.x,ans.y);
    	return 0;
    }
    
  • 相关阅读:
    【Cocos2d-x for WP8 学习整理】(1)创建一个新项目
    与本机其他应用交互的简单介绍
    Windows Phone GB2312
    Windows Phone 横竖屏切换动画
    Linq To VisualTree
    Epub基础知识介绍
    【使用Unity开发Windows Phone上的2D游戏】(2)初识工具
    操作系统Unix、Windows、Mac OS、Linux的故事
    PHP开发环境搭建
    linux和mac
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9179136.html
Copyright © 2011-2022 走看看