程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1379 Run Away(基礎模擬退火)

POJ 1379 Run Away(基礎模擬退火)

編輯:C++入門知識

題目:找出一點,距離所有所有點的最短距離最大
 
http://poj.org/problem?id=1379
 
 
隨機化步長,貪心調整即可。
 
其實用模擬退火需要證明的~~~~%#@&%……@%¥%@證明完畢
 
沒啥好說的,時限和精度要求都不高,隨便搞吧
 
 
[cpp]
#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<queue>  
#include<cmath>  
#include<string>  
#include<vector>  
#include<algorithm>  
#include<map>  
#include<set>  
#include<ctime>  
#define maxn 200005  
#define eps 1e-8  
#define inf 2000000000  
#define LL long long  
#define zero(a) fabs(a)<eps  
#define MOD 19901014  
#define N 1000005  
#define pi acos(-1.0)  
using namespace std; 
int t,n; 
double X,Y; 
double best[50]; 
struct Point{ 
    double x,y; 
    bool check(){ 
        if(x>-eps&&x<eps+X&&y>-eps&&y<eps+Y) 
            return true; 
        return false; 
    } 
}p[1005],tp[50]; 
double dist(Point p1,Point p2){ 
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 

double slove(Point p0){ 
    double ans=inf; 
    for(int i=0;i<n;i++) 
        ans=min(ans,dist(p[i],p0)); 
    return ans; 

int main(){ 
    scanf("%d",&t); 
    srand(time(NULL)); 
    while(t--){ 
        scanf("%lf%lf%d",&X,&Y,&n); 
        for(int i=0;i<n;i++) 
            scanf("%lf%lf",&p[i].x,&p[i].y); 
        for(int i=0;i<15;i++){ 
            tp[i].x=(rand()%1000+1)/1000.0*X; 
            tp[i].y=(rand()%1000+1)/1000.0*Y; 
            best[i]=slove(tp[i]); 
        } 
        double step=max(X,Y)/sqrt(1.0*n); 
        while(step>1e-3){ 
            for(int i=0;i<15;i++){ 
                Point cur,pre=tp[i]; 
                for(int j=0;j<35;j++){ 
                    double angle=(rand()%1000+1)/1000.0*2*pi; 
                    cur.x=pre.x+cos(angle)*step; 
                    cur.y=pre.y+sin(angle)*step; 
                    if(!cur.check()) continue; 
                    double tmp=slove(cur); 
                    if(tmp>best[i]){ 
                        tp[i]=cur; 
                        best[i]=tmp; 
                    } 
                } 
            } 
            step*=0.85; 
        } 
        int idx=0; 
        double ans=0; 
        for(int i=0;i<15;i++){ 
            if(best[i]>ans){ 
                ans=best[i]; 
                idx=i; 
            } 
        } 
        printf("The safest point is (%.1f, %.1f).\n",tp[idx].x,tp[idx].y); 
    } 
    return 0; 

 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<ctime>
#define maxn 200005
#define eps 1e-8
#define inf 2000000000
#define LL long long
#define zero(a) fabs(a)<eps
#define MOD 19901014
#define N 1000005
#define pi acos(-1.0)
using namespace std;
int t,n;
double X,Y;
double best[50];
struct Point{
       double x,y;
       bool check(){
              if(x>-eps&&x<eps+X&&y>-eps&&y<eps+Y)
                     return true;
              return false;
       }
}p[1005],tp[50];
double dist(Point p1,Point p2){
       return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double slove(Point p0){
       double ans=inf;
       for(int i=0;i<n;i++)
              ans=min(ans,dist(p[i],p0));
       return ans;
}
int main(){
       scanf("%d",&t);
       srand(time(NULL));
       while(t--){
              scanf("%lf%lf%d",&X,&Y,&n);
              for(int i=0;i<n;i++)
                     scanf("%lf%lf",&p[i].x,&p[i].y);
              for(int i=0;i<15;i++){
                     tp[i].x=(rand()%1000+1)/1000.0*X;
                     tp[i].y=(rand()%1000+1)/1000.0*Y;
                     best[i]=slove(tp[i]);
              }
              double step=max(X,Y)/sqrt(1.0*n);
              while(step>1e-3){
                     for(int i=0;i<15;i++){
                            Point cur,pre=tp[i];
                            for(int j=0;j<35;j++){
                                   double angle=(rand()%1000+1)/1000.0*2*pi;
                                   cur.x=pre.x+cos(angle)*step;
                                   cur.y=pre.y+sin(angle)*step;
                                   if(!cur.check()) continue;
                                   double tmp=slove(cur);
                                   if(tmp>best[i]){
                                          tp[i]=cur;
                                          best[i]=tmp;
                                   }
                            }
                     }
                     step*=0.85;
              }
              int idx=0;
              double ans=0;
              for(int i=0;i<15;i++){
                     if(best[i]>ans){
                            ans=best[i];
                            idx=i;
                     }
              }
              printf("The safest point is (%.1f, %.1f).\n",tp[idx].x,tp[idx].y);
       }
       return 0;
}
 
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved