萌新求助,代码玄学错误
查看原帖
萌新求助,代码玄学错误
238408
vectorwyxSD省选加油楼主2022/3/16 16:45

RT,代码数组开到 1005 会 RE#9,开到 100005 会 WA#3,不知道为什么QAQ。(思路大概是分段三分)

//author:望远星
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define sml(x,y) (x=cmp(x,y)?x:y)
#define big(x,y) (x=max(x,y))
#define ll long long
#define ull unsigned long long
#define db long double
#define fo(i,x,y) for(int i=x;i<=y;++i)
#define go(i,x,y) for(int i=x;i>=y;--i)
using namespace std;
ull seed=chrono::system_clock::now().time_since_epoch().count();
mt19937 rnd(seed);
inline int rm(int x,int y){return rnd()%(y-x+1)+x;}
inline int read(){int x=0,f=1;unsigned char ch=getchar()-48;while(ch>9){if(ch==253)f=-1;ch=getchar()-48;}while(ch<=9){x=x*10+ch;ch=getchar()-48;}return x*f;}
inline void out(db *a,int l,int r){fo(i,l,r) cout<<*(a+i)<<' ';puts("");}

const int N=100005;
const db eps=1e-10;

struct Point{
	db x,y;
	Point(){} 
	Point(db a,db b){x=a,y=b;} 
	double operator *(const Point &a)const{return x*a.y-y*a.x;}
}P[N],s[N];
typedef Point vec;

vec operator+(const vec &a,const vec &b){return vec(a.x+b.x,a.y+b.y);}
vec operator-(const vec &a,const vec &b){return vec(a.x-b.x,a.y-b.y);}
vec operator*(const vec &a,const db k){return vec(a.x*k,a.y*k);} 
db Dis(const Point &a,const Point &b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

int n,m;
db C,dis[N],a[N],b[N],d[N];
bool cmp(db x,db y){//x是否小于等于y 
	if(fabs(x-y)>=eps) return x<y;
	return 1;
}
bool cmp2(db x,db y){
	if(fabs(x-y)>=eps) return x<y;
	return 0;
}

db calc(db qwq){
	//printf("calc(%.12Lf)\n",qwq);
	int id=0;
	a[1]=qwq;fo(i,2,m) a[i]=a[i-1]+C;
	fo(i,1,m){
		while(id<=n&&cmp(d[id+1],a[i])){
			++id;
		//printf("%d %d\n",i,id);
		if(id>n){
			cout<<id,puts("?");
			printf("%d:%.12Lf,%.12Lf\n",i,a[i],d[n+1]);
		}
		else{
			Point x=P[id],y=id==n?P[1]:P[id+1];
			s[i]=x+(y-x)*((a[i]-d[id])/dis[id]);
			
		}
	}
	double ans=0;
	for(int i=1;i<m;i++) ans+=s[i]*s[i+1];
	ans+=s[m]*s[1];
//	fo(i,1,m-2) ans+=(s[i+1]-s[1])*(s[i+2]-s[1]);
	return abs(ans/2);
}

void init(){
	db mx=0.0;
	int pos=0;
	fo(i,1,n) P[i].x=read(),P[i].y=read();reverse(P+2,P+1+n);
	dis[n]=C=Dis(P[1],P[n]);fo(i,2,n) dis[i-1]=Dis(P[i-1],P[i]),C+=dis[i-1];
	fo(i,1,n) if(dis[i]>mx) mx=dis[i],pos=i;
	Point tmp[N];
	fo(i,1,n) tmp[i]=P[i];
	//cout<<"pos="<<pos<<'\n';
	fo(i,pos,n) P[i-pos+1]=tmp[i];
	fo(i,1,pos-1) P[i+pos]=tmp[i];
	//fo(i,1,n) printf("(%f,%f)\n",P[i].x,P[i].y);
	dis[n]=Dis(P[1],P[n]);fo(i,2,n) dis[i-1]=Dis(P[i-1],P[i]);
}

signed main(){
	cin>>n>>m;
	//逆时针->顺时针 
	init();
	C/=m;
	//顺时针展开成一个 n+1 个点的数轴
	//d 为顶点在数轴上的位置,a 为初始时的 m 个点,b 为决策段拐点 
	fo(i,2,m) a[i]=a[i-1]+C;
	fo(i,1,n+1){
		d[i]=d[i-1]+dis[i-1];
		//b[i]=a[lower_bound(a+1,a+1+m,d[i])-a-1];
		b[i]=d[i]-floor(d[i]/C)*C;
	}b[n+2]=C-2*eps;
	//cout<<"a:";out(a,1,m);cout<<"d:";out(d,1,n+1);cout<<"b:";out(b,1,n+2); 
	//fo(i,1,3) b[n+2+i]=i;
	sort(b+1,b+2+n,cmp2);
	db ans=4e10;
	fo(i,1,n+1){//对 [ b[i],b[i+1] ] 三分 
		//printf("%f,%f\n",b[i],b[i+1]);
		db l=b[i],r=b[i+1];
		if(cmp(C,r)) r=C;
		if(cmp(r,l)) l=r;
		sml(ans,calc(l));sml(ans,calc(r));
		int T=60;
		while(r-l>=eps){
			db lmid=l+(r-l)/3,rmid=l+(r-l)*2/3;
			db x=calc(lmid),y=calc(rmid);
			if(cmp(y,x)) sml(ans,y),l=lmid;
			else sml(ans,x),r=rmid;
		}
	printf("%.10Lf",ans);
	return 0;
}
/*
-------------------------------------------------
*/

2022/3/16 16:45
加载中...