模拟退火学习笔记
[SCOI2010]传送带
方法1:三分套三分
踩坑:第一层三分结束的时候直接返回的solve()函数,这样当第二条传送带长度为0时不会进入第二个三分。所以应该返回tri2()函数。
#include <iostream>
#include <cmath>
using namespace std;
const double eps = 1e-3;
double Ax, Ay, Bx, By, Cx, Cy, Dx, Dy, P, Q, R;
double X1, Y1, X2, Y2;
double dis(double x1, double y1, double x2, double y2) {
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
double f1(double a1, double a2) {
return a1 + (a2 - a1) / 3;
}
double f2(double a1, double a2) {
return a2 - (a2 - a1) / 3;
}
double solve() {
return dis(Ax, Ay, X1, Y1) / P + dis(X1, Y1, X2, Y2) / R + dis(Dx, Dy, X2, Y2) / Q;
}
double tri2(double x1, double y1, double x2, double y2) {
if (dis(x1, y1, x2, y2) < eps) {
X2 = max(x1, x2), Y2 = max(y1, y2);
return solve();
}
double mx1 = f1(x1, x2), mx2 = f2(x1, x2), my1 = f1(y1, y2), my2 = f2(y1, y2);
X2 = mx1, Y2 = my1;
double temp_m1 = solve();
X2 = mx2, Y2 = my2;
double temp_m2 = solve();
if (temp_m1 < temp_m2) {
return tri2(x1, y1, mx2, my2);
}
else {
return tri2(mx1, my1, x2, y2);
}
return -1;
}
double tri1(double x1, double y1, double x2, double y2) {
if (dis(x1, y1, x2, y2) < eps) {
X1 = max(x1, x2), Y1 = max(y1, y2);
return tri2(Cx, Cy, Dx, Dy);
}
double mx1 = f1(x1, x2), mx2 = f2(x1, x2), my1 = f1(y1, y2), my2 = f2(y1, y2);
X1 = mx1, Y1 = my1;
double temp_m1 = tri2(Cx, Cy, Dx, Dy);
X1 = mx2, Y1 = my2;
double temp_m2 = tri2(Cx, Cy, Dx, Dy);
if (temp_m1 < temp_m2) {
return tri1(x1, y1, mx2, my2);
}
else {
return tri1(mx1, my1, x2, y2);
}
return -1;
}
signed main() {
cin >> Ax >> Ay >> Bx >> By >> Cx >> Cy >> Dx >> Dy >> P >> Q >> R;
printf("%.2lf\n", tri1(Ax, Ay, Bx, By));
return 0;
}

浙公网安备 33010602011771号