BZOJ 3680 吊打XXX


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

退火神教

這道題直接模擬退火,判斷是否更優可以這樣:

將所求點u的權值w=∑dist(u,point[i])*point[i].d

顯然,越大的重量離重心越近,這似乎和費馬點有關

當然這道題和[JSOI]平衡點幾乎一樣,應該可以爬山

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int n;
 8 double x[10001],y[10001],w[10001],k,xa,ya,xx,yy,fx,fy,d;
 9 int main()
10 {int i,j,p;
11     cin>>n;
12     for (i=1;i<=n;i++)
13     {
14         scanf("%lf%lf%lf",&x[i],&y[i],&w[i]);
15     }
16     k=100000;
17     xa=0;ya=0;
18     while (k>1e-8)
19      {
20          xx=xa;yy=ya;
21      fx=0;fy=0;
22      for (j=1;j<=n;j++)
23        {
24          d=sqrt((xx-x[j])*(xx-x[j])+(yy-y[j])*(yy-y[j]));
25          if (d) 
26            {
27          double dx=x[j]-xx,dy=y[j]-yy;
28          fx+=dx/d*w[j];fy+=dy/d*w[j];
29            }
30             }
31      xx+=fx*k;yy+=fy*k;
32      xa=xx;ya=yy;
33      k*=0.97;
34      }
35     printf("%.3lf %.3lf\n",xa,ya);
36 }
View Code爬山
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct ZYYS
 8 {
 9   double x,y,d;
10 }a[10001],ans,now,nxt;
11 int n;
12 double T,eps=1e-8;
13 double Rand()
14 {
15   double x=rand()%1000;
16   return x/1000;
17 }
18 double dist(ZYYS u,ZYYS v)
19 {
20   return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y));
21 }
22 double cal(ZYYS u)
23 {int i;
24   double ret=0;
25   for (i=1;i<=n;i++)
26     {
27       ret+=dist(a[i],u)*a[i].d;
28     }
29   if (ans.d>ret) ans=u,ans.d=ret;
30   return ret;
31 }
32 int main()
33 {int i;
34   cin>>n;
35   ans.d=1e15;
36   for (i=1;i<=n;i++)
37     {
38       scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].d);
39       ans.x+=a[i].x;ans.y+=a[i].y;
40     }
41   ans.x/=n;ans.y/=n;
42   cal(ans);
43   T=1000000;
44   now=ans;
45   while (T>0.001)
46     {
47       nxt=now;
48       nxt.x+=T*(Rand()*2-1);
49       nxt.y+=T*(Rand()*2-1);
50       double p=cal(nxt)-cal(now);
51       if (p<-eps||exp(p/T)<Rand()) now=nxt;
52       T*=0.97;
53     }
54   for (i=1;i<=1000;i++)
55     {
56       now.x+=T*(Rand()*2-1);
57       now.y+=T*(Rand()*2-1);
58       cal(now);
59     }
60   printf("%.3lf %.3lf",ans.x,ans.y);
61 }
View Code退火


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM