无题的题 & 模拟退火...

题意:

  给你不超过8条一端在圆心的半径,求他们组成的凸包的最大面积.

SOL:

  正解怎么搞啊不会啊...然后昨天毛爷爷刚讲过模拟退火...那么就打一个吧...

  然后就T了,不过三角形的部分分妥妥的...

  然后在自信的协助下被他改了改参数然后过了九个点...(对着数据调参也是醉了...

  剩下一个点感觉没法搞啊QAQ...差太多了...感觉退完火爬爬山应该会很兹瓷...

90分code:

/*==========================================================================
# Last modified: 
# Filename: .cpp
# Description: 
==========================================================================*/
#define me AcrossTheSky 
#include <cstdio> 
#include <cmath> 
#include <ctime> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 
#include <algorithm> 
  
#include <set> 
#include <map> 
#include <stack> 
#include <queue> 
#include <vector> 
 
#define lowbit(x) (x)&(-x) 
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
#define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
#define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
#define ls(a,b) (((a)+(b)) << 1) 
#define rs(a,b) (((a)+(b)) >> 1) 
#define getlc(a) ch[(a)][0] 
#define getrc(a) ch[(a)][1] 
 
#define maxn 10
#define maxm 100000 
#define limm 1e-6
#define pi acos(-1) 
#define _e 2.718281828459 
#define INF 1070000000 
using namespace std; 
typedef long long ll; 
typedef unsigned long long ull; 
 
template<class T> inline 
void read(T& num) { 
    bool start=false,neg=false; 
    char c; 
    num=0; 
    while((c=getchar())!=EOF) { 
        if(c=='-') start=neg=true; 
        else if(c>='0' && c<='9') { 
            start=true; 
            num=num*10+c-'0'; 
        } else if(start) break; 
    } 
    if(neg) num=-num; 
} 
/*==================split line==================*/
int a[maxn],temp[maxn],tmp[maxn];
double angle[maxn];
int n;
double ans=0; 
bool vis[maxn];
set<int> s; 
int cmp(int x,int y){return x>y;}
double getang(double x){ return x/180*pi; }
double calc(int ord,double ang,int m){
	return temp[ord]*temp[ord%m+1]*sin(getang(ang))/2;
}
int getposb(double c,double b){
	double tttt=exp(c/b);
	return tttt;
}
void work(int m){
	double aaa=360.0/m;
	double sum=0;

	FORP(i,1,m) { angle[i]=aaa; sum+=calc(i,angle[i],m); }
	//angle[m]=360-aaa;
	//sum+=calc(m,angle[m],m);
	double maxx=sum;
	//ans=max(ans,sum);
	double T=100;
	if (n < 4) T = 1000;
	while (fabs(T-0)>1e-5){
		if (maxx < 94*ans/100) return;
		int pos=rand()%m+1,next=pos%m+1;
		double ttemp=calc(pos,angle[pos],m)+calc(next,angle[next],m);
		
		ll cap=trunc(max(angle[pos],angle[next])*100000000/T);
		double change=(rand()%cap)*T/100000000;
		
		double dx,dy;
		if (angle[pos]-change<0) dx=angle[pos]+change,dy=angle[next]-change;
			else dx=angle[pos]-change,dy=angle[next]+change;
		
		double delta=calc(pos,dx,m)+calc(next,dy,m)-ttemp;
		if (delta>0){
			sum+=delta;
			angle[pos]=dx,angle[next]=dy;
		}
		else{
			double posb=getposb(delta,ans*T);
			int xxx=10000000/trunc(T);
			int rp=rand()%xxx;
			if ((double)rp*T/100000000.0<posb) {
				sum+=delta;
				angle[pos]=dx,angle[next]=dy;
			}
		}
		if (sum>ans) {
			//FORP(i,1,m) printf("%d ",temp[i]);
			//cout << endl;
			//FORP(i,1,m) printf("%lf ",angle[i]);
			//cout << endl;
			//printf("%lf\n",sum);
			ans=sum;
		}
		maxx=max(maxx,sum);
		if (n >= 4) T*=0.89;
		else T *= 0.999;
	}
	if (sum>ans) ans=sum;
}
int fpow(int s,int m){
	int ret=1;
	for (;m;m>>=1,s=s*s) if (m&1) ret*=s;
	return ret;
}
void dfs(int x,int m,int tot){
	if (x==m+1) {

			work(m);work(m);
			work(m);work(m);
		return;
	}
	FORP(i,1,n)
		if (!vis[i]) {
		vis[i]=true; temp[x]=a[i]; dfs(x+1,m,tot*10+i); vis[i]=false;
	}
}
int main(){
	srand(time(0));
	freopen("yist.in","r",stdin);
	freopen("yist.out","w",stdout);
	read(n); bool flag=true;
	if (n==2) {printf("0\n"); return 0;}
	FORP(i,1,n) read(a[i]);
	FORP(i,1,n) { if (i>1 & a[i]!=a[i-1]) flag=false; }
	if (flag){
		if (n==3) printf("%.8lf\n",a[1]*sqrt(3)*(a[1]+a[1]/2.0)/2.0);
		else printf("%.8lf",(double)a[1]*a[1]*sin(2*pi/n)*n/2.0);
	}
	else{
		if (n==3){
			FORP(i,1,n) temp[i]=a[i];
			dfs(1,n,0);
		}
		else{
			FORP(i,3,n-1){
				memset(vis,false,sizeof(vis));
				//s.clear();
				dfs(1,i,0);
			}
			memset(vis,false,sizeof(vis));
			s.clear(); temp[1]=1; vis[1]=1;
			dfs(2,n,0);
		}
		printf("%.10lf\n",ans);
	}
}

 

posted @ 2016-04-07 21:19  YCuangWhen  阅读(234)  评论(0编辑  收藏  举报