哎!还是没有掌握模拟退火的精髓啊!继续努力吧!
题意:给出多边形外点的坐标Mi和该点与多边形相邻两点的夹角AiMiAi+1,求多边形的各个顶点坐标。
思路:初始化一个点作为多边形的第一个点(顺时针方向),这里取原点,向八个方向进行移动得到 t,由第一个点根据坐标旋转求出其他各个点,取t与rp[0]到rp[n]最近的点作为rp[0](最后rp[0]==rp[n]),直到降温结束。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<math.h>
#define F(i,n) for(int i=0;i<n;i++)
#define pi acos(-1.0)
#define Max(a,b) a>b?a:b
#define Min(a,b) a<b?a:b
#define maxn 55
#define eps 1e-8
#define sqr(x) ((x)*(x))
using namespace std;
int dr[8][2]={0,1,1,1,1,0,1,-1,0,-1,-1,-1,-1,0,-1,1,};
struct cpoint
{
double x,y;
};
cpoint cp[maxn];
int n;
double angle[maxn];
double dis(cpoint p,cpoint q)
{
return sqrt(sqr(p.x-q.x)+sqr(p.y-q.y));
}
cpoint rotating(cpoint p,cpoint q,double angle)
{
cpoint res;
double x=q.x-p.x;
double y=q.y-p.y;
res.x=x*cos(angle)-sin(angle)*y+p.x;
res.y=x*sin(angle)+cos(angle)*y+p.y;
return res;
}
void solve()
{
double dal=1000.00;
cpoint rp[maxn];
rp[0].x=0;
rp[0].y=0;
cpoint t;
while(dal>eps)
{
F(i,8)
{
t.x=rp[0].x+dr[i][0]*dal;
t.y=rp[0].y+dr[i][1]*dal;
for(int j=1;j<=n;j++)
{
rp[j]=rotating(cp[j-1],rp[j-1],angle[j-1]);
}
if(dis(t,rp[n])<dis(rp[0],rp[n]))
rp[0]=t;
}
dal*=0.98;
}
F(i,n) printf("%d %d\n",(int)(rp[i].x+0.5),(int)(rp[i].y+0.5));
}
int main()
{
double a;
while(scanf("%d",&n)!=EOF)
{
F(i,n)
{
scanf("%lf %lf",&cp[i].x,&cp[i].y);
}
F(i,n)
{
scanf("%lf",&a);
angle[i]=a*pi/180.00;
}
solve();
}
return 0;
}