# 平衡点 / 吊打XXX（洛谷-P1337）

## 输入输出样例

3
0 0 1
0 2 1
1 1 1

0.577 1.000

• 如果小于当前答案的代价，更新答案
• 如果大于当前答案的代价，有一定概率更新答案

## 源代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; }
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-15;
const int MOD = 1000000000+7;
const int N = 1000+5;
const int dx[] = {0,0,1,-1,1,1,-1,-1};
const int dy[] = {1,-1,0,0,1,-1,1,-1};
using namespace std;

struct Node{
int x, y;
int w;
} node[N];
int n;
double getDis(double x1,double y1,double x2,double y2){
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
double getRes(double x, double y) {//计算n个到选定(x,y)的距离乘以重量之和
double res = 0.0;
for (int i = 1; i <= n; i++)
res += (double)getDis(x, y, node[i].x, node[i].y) * node[i].w;
return res;
}
void SA(double &x, double &y) {
double T = 3000;//初始温度
double delta = 0.99;
double res = getRes(x, y);//当前状态结果
while (T > EPS) {
double nx = x + (rand() * 2 - RAND_MAX) * T;//转移x状态
double ny = y + (rand() * 2 - RAND_MAX) * T;//转移y状态
double newRes = getRes(nx, ny);新状态下的结果
double pr = exp((res - newRes) / T) * RAND_MAX;
if (newRes < res || pr > rand()) {
x = nx;//更新x状态
y = ny;//更新y状态
res = newRes;
}
T *= delta;
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].w);

srand(time(0));
srand(rand());
srand(rand());
double x = 0.0, y = 0.0;//初始状态
for (int i = 1; i <= 10; i++)//模拟退火10次
SA(x, y);
printf("%.3lf %.3lf", x, y);
return 0;
}


• 点赞
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

Alex_McAvoy

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文
02-14 9106

12-02 8万+
10-19 1万+
03-30 130
02-03 12
04-02 53
02-03 630