爬山游记

爬山游记

爬啊爬

我爱大自然(雾

JSOI2016 炸弹攻击

由于是随机坐标,且ans是整数变化不大,我们可以使用一半的模拟退火一半的爬山

#include<bits/stdc++.h>
#include<ctime>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N = 2001;
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ROF(i,a,b) for(int i=a;i>=b;--i)
int n,a[N],x[N],y[N],r[N],p[N],q[N],m;
double R,st;
int read(){
	int x=0,pos=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
	return pos?x:-x;
}
const double eps= 1e-10;
double dis(double a,double b,double c,double d){
	return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
double calc(int nx,int ny){
	double nd=R;
	FOR(i,1,n){
		nd=min(nd,dis(nx,ny,x[i],y[i])-r[i]);
	}
	int res=0;
	FOR(i,1,m){
		if(dis(nx,ny,p[i],q[i])<nd+eps) res++;
	}
	return res;
}
double X,Y;
int SA(double nx,double ny){
	double T=2000,t0=2000;double ans=calc(nx,ny);
	while(T>eps){
	//	if(1000*(clock()-st)>=970*CLOCKS_PER_SEC) break;
		double tx=nx+1.0*(rand()*2-RAND_MAX)*T;
		double ty=ny+1.0*(rand()*2-RAND_MAX)*T;
		double delta=calc(tx,ty)-ans;
		if(delta>0){
			ans+=delta,nx=tx,ny=ty;
		}//else if(1.0*exp(delta/T)*RAND_MAX>1.0*rand()){
	//		ans+=delta,nx=tx,ny=ty;
	//	}
		T*=0.998;
	}
	if(ans<0) return 0;
	else return (int)(ans);
}
int main(){
	
	srand(time(0));
	n=read();m=read();R=read();st=clock();
	double sx=0,sy=0;
	FOR(i,1,n){
		x[i]=read(),y[i]=read(),r[i]=read(); 
	}
	FOR(i,1,m){
		p[i]=read(),q[i]=read();
		sx=sx+p[i];sy=sy+q[i];
		X=X+abs(p[i]);Y=Y+abs(q[i]);
	}
	sx/=m,sy/=m;
	X/=m,Y/=m;
	int ans=0;
	while(1000*(clock()-st)<900*CLOCKS_PER_SEC){
		ans=max(ans,SA(sx*rand()/RAND_MAX,sy*rand()/RAND_MAX));
	}
	printf("%d\n",ans);
	return 0;
}

WC2018 通道

乱搞,利用树的直径的思想(?)

74~87分

#include<bits/stdc++.h>
using namespace std;
int read(){
	int x=0,pos=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
	return pos?x:-x;
} 
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
const int N = 1e5+200;
int n;
int R(int now){
	return rand()%now+1;
}
struct graph{
	#define pil pair<int,ll>
	#define fi first
	#define se second
	vector<pil>G[N];
	int fa[N],sz[N],dep[N],son[N],top[N],vis[N];ll val[N];/*
	void dfs1(int now,int pre){
		fa[now]=pre;dep[now]=dep[pre]+1;sz[now]=1;
		for(int i=0;i<G[now].size();i++){
			int v=G[now][i].fi;
			if(v==pre) continue;
			val[v]=G[now][i].se+val[now];
			dfs1(v,now);
			if(sz[v]>sz[son[now]]) son[now]=v;
		}
	}
	void dfs2(int now,int tp){
		top[now]=tp;
		if(son[now]) dfs2(son[now],tp);
		for(int i=0;i<G[now].size();i++){
			int v=G[now][i].fi;
			if(v==fa[now]||v==son[now]) continue;
			dfs2(v,v);
		}
	}
	int lca(int a,int b){
		while(top[a]!=top[b]){
			if(dep[top[a]]<dep[top[b]]) swap(a,b);
			a=fa[top[a]];
		}
		if(dep[a]>dep[b]) swap(a,b);return a;
	}
	ll query(int a,int b){
		return val[a]+val[b]-2*val[lca(a,b)];
	}
	int getnex(int now){
		return G[now][R(G[now].size())-1].fi;
	}*/
	void dfs(int now,int pre){
		for(int i=0;i<G[now].size();i++){
			int v=G[now][i].fi;
			if(v==pre) continue;
			val[v]=G[now][i].se+val[now];
			dfs(v,now);
			if(sz[v]>sz[son[now]]) son[now]=v;
		}
	}
	void init(){
		FOR(i,1,n-1){
			int u=read(),v=read();ll w;scanf("%lld",&w);
			G[u].push_back(make_pair(v,w));
			G[v].push_back(make_pair(u,w));
		}
	}
}g[3];
ll ans=0;
ll calc(int now){
	return g[0].val[now]+g[1].val[now]+g[2].val[now];
}
ll getans(int u){
	FOR(i,0,2){
		FOR(j,1,n) g[i].val[j]=0;
		g[i].dfs(u,0);
	}
	ll an=0;int res=0;
	FOR(i,1,n){
		if(i==u) continue;
		if(calc(i)>an){
			res=i,an=calc(i);
		} 
	}
	ans=max(ans,an);
	return res;
}
const double eps = 1e-9;
void SA(){
	int s=R(n),t;
	FOR(i,1,10){
		t=getans(s);swap(s,t);
	} 
}
int main(){
	srand(time(0));
	n=read();
	g[0].init();g[1].init();g[2].init();
	FOR(i,1,13) SA();
	printf("%lld\n",ans);
	return 0;
}
posted @ 2021-02-02 10:25  lcyfrog  阅读(77)  评论(0编辑  收藏