poj2420 A Star not a Tree?
题意:给你n个点,求一个点到这n个点距离和最短的点。
思路:典型的费马点问题,点数比较少,可以用退火来做。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define pi acos(-1)
#define maxn 11111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8
#define pb push_back
#define mem(a) memset(a,0,sizeof a)
using namespace std;
#define T 100
#define det 0.98
int n;
int dx[5] = {0, 1, 0, -1, 0};
int dy[5] = {0, 0, 1, 0, -1};
struct Point {
double x, y;
};
Point p[maxn];
double dis(Point A, Point B) {
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
double tot(Point A) {
double ans = 0.0;
for(int i = 1; i <= n; i++) {
ans += dis(A, p[i]);
}
return ans;
}
double sov() {
Point s = p[1];
double t = T;
double ans = INF;
while(t > eps) {
bool fa = 1;
while(fa) {
fa = 0;
Point temp;
for(int i = 1; i <= 4; i++) {
temp.x = s.x + dx[i] * t;
temp.y = s.y + dy[i] * t;
double DIS = tot(temp);
if(DIS < ans) {
s = temp;
ans = DIS;
fa = 1;
}
}
}
t *= det;
}
return ans;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%lf%lf", &p[i].x, &p[i].y);
}
double ans = sov();
printf("%.0f\n", ans);
return 0;
}
poj2069 Super Star
题意:给你n个点,求一个最小球能包含这n个点
思路:其实就是求一个定点,到n个点距离最大值最小。和上题差不多。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define pi acos(-1)
#define maxn 11111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8
#define pb push_back
#define mem(a) memset(a,0,sizeof a)
using namespace std;
#define T 10000
#define det 0.99
int n;
int dx[7] = {0, 1, 0, 0, -1, 0, 0};
int dy[7] = {0, 0, 1, 0, 0, -1, 0};
int dz[7] = {0, 0, 0, 1, 0, 0, -1};
struct Point {
double x, y, z;
};
Point p[maxn];
double dis(Point A, Point B) {
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) + (A.z - B.z) * (A.z - B.z));
}
double cal(Point A) {
int k = 0;
double vk = 0.0;
for(int i = 1; i <= n; i++) {
double DIS = dis(A, p[i]);
if(DIS > vk) {
k = i;
vk = DIS;
}
}
return vk;
}
double sov(void) {
double ans = INF;
double t = T;
Point s = p[1];
while(t > eps) {
int k = 1;
for(int i = 1; i <= n; i++) {
if(dis(s, p[i]) > dis(s, p[k])) {
k = i;
}
}
double temp = dis(s, p[k]);
s.x += (p[k].x - s.x) / temp * t;
s.y += (p[k].y - s.y) / temp * t;
s.z += (p[k].z - s.z) / temp * t;
ans = min(temp, ans);
t *= det;
}
return ans;
}
int main() {
while(scanf("%d", &n) && n != 0) {
for(int i = 1; i <= n; i++) {
scanf("%lf%lf%lf", &p[i].x, &p[i].y,&p[i].z);
}
double ans = sov();
printf("%.5f\n", ans);
}
return 0;
}
HDU2899 Strange fuction
题意:给你一个函数,求函数极值问题。
思路:典型的问题
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<time.h>
#define pi acos(-1)
#define maxn 11111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8
#define pb push_back
#define mem(a) memset(a,0,sizeof a)
using namespace std;
#define T 100
#define det 0.98
double y;
bool pan(double temp) {
if(temp >= 0.0 && temp <= 100.0) return 1;
else return 0;
}
double getsum(double x) {
return 6.0*x*x*x*x*x*x*x + 8.0*x*x*x*x*x*x + 7.0*x*x*x + 5.0*x*x - y*x;
}
double sov() {
double t = T;
double x = 0.0;
double ans = getsum(x);
while(t > eps) {
bool fa = 1;
while(fa) {
fa = 0;
double temp = x + t;
if(pan(temp) && getsum(temp) < ans && fabs(ans - getsum(temp)) > eps ) {
x = temp;
ans = getsum(temp);
fa = 1;
}
temp = x - t;
if(pan(temp) && getsum(temp) < ans && fabs(ans - getsum(temp)) > eps ) {
x = temp;
ans = getsum(temp);
fa = 1;
}
}
t *= det;
}
return ans;
}
int main() {
int kase;
scanf("%d", &kase);
while(kase--) {
scanf("%lf", &y);
printf("%.4f\n", sov());
}
return 0;
}