POJ 1379 (随机算法)模拟退火

题目大意:

给定一堆点,找到一个点的位置使这个点到所有点中的最小距离最大

这里数据范围很小,精度要求也不高,我们这里可以利用模拟退火的方法,随机找到下一个点,如果下一个点比当前点优秀就更新当前点

参考:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

http://wenku.baidu.com/view/0c6b5df5f61fb7360b4c65a9.html

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <climits>
 6 #include <cmath>
 7 #include <queue>
 8 #include <cstdlib>
 9 #include <ctime>
10 using namespace std;
11 #define random(x) ((rand()%x)+1)
12 #define N 1005
13 #define ll long long
14 #define eps 1e-4
15 const double PI = acos(-1.0);
16 const int INF = INT_MAX;
17 const int P = 20;
18 const int L = 30;
19
20 double x,y;
21 int n;
22 double dist[N];
23
24 struct Point{
25     double x,y;
26     Point(double x=0 , double y=0):x(x),y(y){}
27 }p[N] , tmp[N];
28
29 double dis(Point a , Point b)
30 {
31     double x = a.x-b.x , y = a.y - b.y;
32     return sqrt(x*x+y*y);
33 }
34
35 double min_dis(Point t)
36 {
37     double minn = 1e20;
38     for(int i=0 ; i<n ; i++) minn=min(minn , dis(t , p[i]));
39     return minn;
40 }
41
42 bool ok(Point t)
43 {
44     return t.x>=0 && t.x<=x && t.y>=0 && t.y<=y;
45 }
46
47 int main()
48 {
49     #ifndef ONLINE_JUDGE
50         freopen("a.in" , "r" , stdin);
51     #endif // ONLINE_JUDGE
52     srand(time(0));
53     int T;
54     scanf("%d" , &T);
55     while(T--)
56     {
57         Point ans;
58         double ret=0;
59
60         scanf("%lf%lf%d" , &x , &y , &n);
61         for(int i=0 ; i<n ; i++){
62             scanf("%lf%lf" , &p[i].x , &p[i].y);
63         }
64
65         for(int i=0 ; i<P ; i++){
66             tmp[i].x = random(1000)/1000.0*x;
67             tmp[i].y = random(1000)/1000.0*y;
68             dist[i] = min_dis(tmp[i]);
69         }
70         double step = sqrt(x*x+y*y)/2;
71         while(step>eps){
72
73             for(int i=0 ; i<P ; i++){
74                 Point cur;
75                 for(int j=0 ; j<L ; j++){
76                     double ang = random(1000)/1000.0*2*PI;
77                     cur.x = tmp[i].x+cos(ang)*step;
78                     cur.y = tmp[i].y+sin(ang)*step;
79                     if(!ok(cur)) continue;
80                     double val = min_dis(cur);
81                     if(val>dist[i]){
82                         tmp[i]=cur;
83                         dist[i] = val;
84                     }
85                 }
86             }
87             step *= 0.85;
88         }
89
90         for(int i=0 ; i<P ; i++){
91             if(dist[i]>ret){
92                 ret = dist[i];
93                 ans = tmp[i];
94             }
95         }
96         printf("The safest point is (%.1f, %.1f).\n" , ans.x , ans.y);
97     }
98     return 0;
99 }
时间: 2024-11-11 21:25:15

POJ 1379 (随机算法)模拟退火的相关文章

POJ 1379 Run Away 模拟退火

一开始写了一发很快的,发现一会能过一会不能,貌似有点悬,毕竟是随机算法. 后来重写了一发迭代5遍的,基本上把把AC了= = 模拟退火果然是一种不是很靠谱的算法. #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; const

poj 1379 Run Away 模拟退火 难度:1

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6482   Accepted: 1993 Description One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look complet

POJ 1379 模拟退火算法

求规定平面上一点到已知点的最小距离最大的点. 模拟退火的流程是,随机构造几组解作为初始解空间,每次对当前解空间进行随机扩展,若发现更优解则替换. 进行的次数由参数人为控制,而随机扩展的幅度也是随着次数逐渐减小的. #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #include<string> #include&

POJ 3318:Matrix Multiplication(随机算法)

http://poj.org/problem?id=3318 题意:问A和B两个矩阵相乘能否等于C. 思路:题目明确说出(n^3)的算法不能过,但是通过各种常数优化还是能过的. 这里的随机算法指的是随机枚举矩阵C的一个位置,然后通过A*B计算是否能够得到矩阵C相应位置的数,如果不等,就直接退出了,如果跑过一定的数量后能够相等,那么就可以判断这个矩阵C等于A*B的.第一次见这样的题目...有点新奇. 暴力算法: 1 #include <cstdio> 2 using namespace std;

随机算法 poj 2576 Tug of War

Tug of War Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8187   Accepted: 2204 Description A tug of war is to be arranged at the local office picnic. For the tug of war, the picnickers must be divided into two teams. Each person must b

POJ 1379

模拟退火算法. 随机MAX个点,然后,退火移动,选取距离所有点中最短中最长者即可.理解和我上一篇一样. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> using namespace std; const int MAXN=1010; const int MA

POJ 1379 模拟退火法

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5631   Accepted: 1728 Description One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look complet

浅谈欧洲算法——模拟退火

初听说退火这个名词感觉就很(zhuang)帅(A__CDEFG...) 直到学了退火之后,我才发现: 退火不只是帅,而且非常万能 甚至比 D (大) F (法) S (师)还要万能 简直就是骗(de)分神器啊 简介 作为一个计算机算法,它竟然在百度上有物理词条! 当时我看了就懵了,你说计算机一个算法,跟冶炼金属有什么关系啊? 后来我看了算法的词条... 是不是更懵了... 方便大家理解(变得更懵),我搬了百度上的定义: Simulate Anneal Arithmetic (SAA,模拟退火算法

Miller_Rabin算法(随机算法,判断一个数是否是素数)

1 const int S = 20;//随机算法判定次数,S越大,判错概率越小 2 LL pow_mod(LL a, LL b, LL mod) { // a^b%mod 3 LL ans = 1; 4 a = a % mod; 5 while(b) { 6 if(b & 1) { 7 ans = (ans * a) % mod; 8 } 9 a = ( a * a ) % mod; 10 b >>= 1; 11 } 12 return ans; 13 } 14 bool check

微信红包随机算法

最近看了一篇文章,讲微信红包随机算法的.感觉很不错,所以自己实现了下,并进行了简单测试. 算法 算法很简单,不是提前算好,而是抢红包时计算: 红包里的金额怎么算?为什么出现各个红包金额相差很大?答:随机,额度在0.01和剩余平均值*2之间. 实现 实现上述算法的逻辑主要是: public static double getRandomMoney(RedPackage _redPackage) { // remainSize 剩余的红包数量 // remainMoney 剩余的钱 if (_red