首页 技术 正文
技术 2022年11月18日
0 收藏 757 点赞 4,420 浏览 2817 个字

模拟退火算法。。。。

这道题,呃。我怎么感觉他就是随机的。同一个代码,时而AC,时而WA。其实还真的是随机的。呵呵呵呵呵。。。因为下降火太快了,没办法,而降得慢又会。。。TLE,虽然精度提高了。

敢问,还有什么好的方法?我是在做退火算法时遇到这个练手的。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <time.h>using namespace std;
const int MAXN=55;
const double PI=3.141592653;
const double eps=1e-5;#define zero(a) fabs(a)<epsstruct point {
double x,y;
};
struct Segment{
point a,b;
};point p[MAXN]; int n; double ans; int cot;
point tar[MAXN]; double best[MAXN]; double R;point operator -(point &u,point &v){
point re;
re.x=u.x-v.x; re.y=u.y-v.y;
return re;
}double dot(point &u,point &v){
return u.x*v.x+u.y*v.y;
}double dist(point tt){
return sqrt(tt.x*tt.x+tt.y*tt.y);
}
double multi(point &u,point &v){
return u.x*v.y-u.y*v.x;
}
/*
bool whether_in(point &t){
double angle=0;
for(int i=0;i<n;i++){
point A=p[i]-t;
point B=p[i+1]-t;
angle+=acos(dot(A,B)/dist(A)/dist(B));
}
if(fabs(angle-PI*2)<1e-5)
return true;
return false;
}*/double xmul(point p0,point p1,point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}bool online(point p1,point p2,point p){
if(zero(xmul(p1,p2,p))&&((p.x-p1.x)*(p.x-p2.x)<eps&&(p.y-p1.y)*(p.y-p2.y)<eps))
return true;
return false;
}inline bool across(Segment s1,Segment s2){
if(xmul(s1.a,s1.b,s2.a)*xmul(s1.a,s1.b,s2.b)<eps)
if(xmul(s2.a,s2.b,s1.a)*xmul(s2.a,s2.b,s1.b)<eps)
return true;
return false;
}bool whether_in(point cen){
int cnt=0;
Segment s,e;
s.a=cen;s.b.y=cen.y;s.b.x=20000.0;
for(int i=0;i<n;i++){
e.a=p[i];e.b=p[i+1];
if(online(p[i],p[i+1],cen)) return false;
if(zero(p[i].y-p[i+1].y)) continue;
if(online(s.a,s.b,p[i])){
if(p[i].y>p[i+1].y) cnt++;
}
else if(online(s.a,s.b,p[i+1])){
if(p[i+1].y>p[i].y) cnt++;
}
else if(across(s,e))
cnt++;
}
return cnt&1;
}double count_d(point &tt){
double mm=1e10; double tp;
for(int i=0;i<n;i++){
point A=tt-p[i];
point B=p[i+1]-p[i];
if(dot(A,B)<=0){
tp=dist(A);
// cout<<"1"<<' '<<tp<<endl;
mm=min(mm,tp);
continue;
}
A=tt-p[i+1];
B=p[i]-p[i+1];
if(dot(A,B)<=0){
tp=dist(A);
mm=min(mm,tp);
//cout<<"2"<<' '<<tp<<endl;
continue;
}
double area=multi(A,B);
tp=fabs(area)/dist(p[i]-p[i+1]);
//cout<<"3"<<' '<<tp<<endl;
mm=min(mm,tp);
}
return mm;
}double getdouble(){
double re=((rand()*rand())%1000000)*1.0/1e6;
return re;
}int main(){
srand(time(0));
while(scanf("%d",&n),n){
cot=0;
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%lf",&R);
p[n]=p[0];
point tmp;
for(int i=0;i<n;i++){
tmp.x=(p[i].x+p[i+1].x)/2;
tmp.y=(p[i].y+p[i+1].y)/2;
tar[cot++]=tmp;
}
//cout<<cot<<endl;
bool flag=false;
for(int i=0;i<cot;i++){
best[i]=0;
}
//cout<<"YES"<<endl;
double T=50;
for(double t=T;t>1e-4;t*=0.55){
for(int i=0;i<cot;i++){
for(int j=0;j<10;j++){
double td=getdouble();
if(rand()&1) td*=-1;
tmp.x=tar[i].x+td*t;
td=getdouble();
if(rand()&1) td*=-1;
tmp.y=tar[i].y+td*t;
if(whether_in(tmp)){
td=count_d(tmp);
if(td>best[i]){
best[i]=td;
tar[i]=tmp;
}
if(td>=R||fabs(td-R)<1e-4){
//cout<<tmp.x<<' '<<tmp.y<<endl;
//cout<<td<<endl;
flag=true;
break;
}
}
}
if(flag) break;
}
if(flag) break;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,581
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918