QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#84209 | #5667. Meeting Places | changtu | WA | 3ms | 12160kb | C++20 | 5.4kb | 2023-03-05 22:55:57 | 2023-03-05 22:55:58 |
Judging History
answer
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<iomanip>
using namespace std;
// #define debug(x) cout<<"[debug]"#x<<"="<<x<<endl
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f,mod=2147483647;
const ld eps=1e-7;
#define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
#define debug(...)
#include<debug>
#else
#define debug(...)
#endif
const ld pi=acos(-1);
using _T=long double;
template<typename T> struct point
{
T x,y;
bool operator ==(const point &a) const {return abs(x-a.x)<eps&&abs(y-a.y)<eps;}
point operator +(const point &a) const {return {x+a.x,y+a.y};}
point operator -(const point &a) const {return {x-a.x,y-a.y};}
point operator -() const{return {-x,-y};}
point operator *(const T k) const {return {k*x,k*y};}
point operator /(const T k) const {return {x/k,y/k};}
T operator *(const point &a) const {return x*a.x+y*a.y;}//Dot
T operator ^(const point &a) const {return x*a.y-a.x*y;}//Cross
bool operator <(const point &a) const {if(abs(x-a.x)<eps) return y<a.y-eps; return x<a.x-eps;}
bool is_par(const point &a) const {return abs((*this)^a)<=eps;}
bool is_ver(const point &a) const {return abs((*this)*a)<=eps;}
int toleft (const point &a) const {auto t=(*this)^a; return (t>eps)-(t<-eps);}//在左侧为1
T len2() const {return (*this)*(*this);}
T dis2(const point &a) const {return (a-(*this)).len2();}
long double len() const {return sqrt(len2());}//点到原点的距离
long double dis(const point &a) const {return (a-(*this)).len();};//两点之间的距离
long double ang(const point &a) const {return acos(((*this)*a)/(this->len()*a.len()));}//两个向量的夹角
point rot(const long double rad) const {return {x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad)};}// 逆时针旋转(给定角度)
point rot(const long double cosr,const long double sinr) const {return {x*cosr-y*sinr,x*sinr+y*cosr};}// 逆时针旋转(给定角度的正弦与余弦)
};
using Point=point<_T>;
template<typename T> struct line
{
point<T> p,v;//p+vt
bool operator ==(const line &a) const {return v.toleft(a.v)==0&&v.toleft(p-a.p)==0;}//两条直线是否重合
bool is_par(const line &a) const {return (v.is_par(a.v)&&!v.is_par(p-a.p));}//平行且不重合为true
bool is_ver(const line &a) const {return v.is_ver(a.v);}//两条直线是否垂直
bool is_on(const point<T> &a) const {return v.is_par(a-p);}//点是否在直线上
int toleft(const point<T> &a) const {return v.toleft(a-p);}//点在直线向量方向的左侧为1,右侧为-1,直线上为0
point<T> inter(const line &a) const {return p+v*((a.v^(p-a.p))/(v^a.v));}//求两条直线的交点
long double dis(const point<T> &a) const {return abs(v^(a-p)/v.len());}//点到直线的距离
long double get_rad() const {return atan2(v.y,v.x);}
point<T> proj(const point<T> &a) const {return p+v*((v*(a-p))/(v*v));}//点在向量v上的投影坐标
long double proj_len(const point<T> &a) const {return (v*a)/v.len();}//向量在向量v上的投影长度
};
using Line=line<_T>;
struct Circle
{
Point o;//圆心
ld r;//半径
};
int dcmp(ld x,ld y)
{
if(fabs(x-y)<eps)
return 0;
else if(x<y) return -1;
else return 1;
}
Circle get_circle(Point a,Point b,Point c)//三点确定一个圆
{
Line l1={ (a+b)/2 , (a-b).rot(pi/2)};
Line l2={ (a+c)/2 , (a-c).rot(pi/2)};
Point o=l1.inter(l2);//此为圆心
return {o,o.dis(a)};
}
const int N=2003;
ld dp[N][N];
int n,k;
Point p[N];
int x[N],y[N];
ld w[N][N];
int main()
{
cerr<<fixed<<setprecision(2);
scanf("%d%d%d",&n,&k,&x[1]);
y[1]=(233811181ll*x[1]+1)%mod;
for(int i=2;i<=n;i++)
{
x[i]=(233811181ll*y[i-1]+1)%mod;
y[i]=(233811181ll*x[i]+1)%mod;
}
for(int i=1;i<=n;i++)
{
p[i]={(ld)x[i],(ld)y[i]};
}
for(int fir=1;fir<=n;fir++)
{
Circle c={p[fir],0};
for(int i=fir+1;i<=n;i++)
{
if(dcmp(c.o.dis(p[i]),c.r)>0)
{
c={p[i],0};
for(int j=1;j<i;j++)
{
if(dcmp(c.o.dis(p[j]),c.r)>0)
{
c={(p[i]+p[j])/2,p[i].dis(p[j])/2};
for(int k=1;k<j;k++)
{
if(dcmp(c.o.dis(p[k]),c.r)>0)
{
c=get_circle(p[i],p[j],p[k]);
}
}
}
}
}
w[fir][i]=c.r;
}
}
vector<vector<pair<ld,int>>> ver(n+1);
for(int last=1;last<=n;last++)
{
ver[last].push_back({w[1][last],1});
for(int i=2;i<=last;i++)
{
if(!dcmp(ver[last].back().first,w[i][last])) continue;
ver[last].push_back({w[i][last],i});
}
}
for(int i=0;i<=n;i++)
for(int j=0;j<=k;j++)
dp[i][j]=0x3f3f3f3f3f3f3f3f;
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=min(i,k);j++)
{
for(auto [g,id]:ver[i])
{
dp[i][j]=min(dp[i][j],dp[id-1][j-1]+g);
}
}
}
printf("%.10Lf\n",dp[n][k]);
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 12160kb
input:
100 23 213
output:
1319350480.8007325387
result:
ok found '1319350480.8007326', expected '1319350480.8007326', error '0.0000000'
Test #2:
score: 0
Accepted
time: 3ms
memory: 7760kb
input:
10 1 1060
output:
1042753143.3451676866
result:
ok found '1042753143.3451676', expected '1042753143.3451676', error '0.0000000'
Test #3:
score: 0
Accepted
time: 3ms
memory: 5740kb
input:
10 10 2373
output:
0.0000000000
result:
ok found '0.0000000', expected '0.0000000', error '-0.0000000'
Test #4:
score: -100
Wrong Answer
time: 2ms
memory: 5680kb
input:
10 2 3396
output:
1305327616.8448314156
result:
wrong answer 1st numbers differ - expected: '1236610536.9469230', found: '1305327616.8448315', error = '0.0555689'