QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#367306#7846. Glacier TravelkevinyangAC ✓30ms4084kbC++175.2kb2024-03-25 21:00:432024-03-25 21:00:43

Judging History

你现在查看的是最新测评结果

  • [2024-03-25 21:00:43]
  • 评测
  • 测评结果:AC
  • 用时:30ms
  • 内存:4084kb
  • [2024-03-25 21:00:43]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define double long double
double eps = 1e-7;
template <class T> int sgn(T x) { return (x > 0) - (x < 0); }
template<class T>
struct Point {
    typedef Point P;
    T x, y;
    explicit Point(T x=0, T y=0) : x(x), y(y) {}
    bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); }
    bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); }
    P operator+(P p) const { return P(x+p.x, y+p.y); }
    P operator-(P p) const { return P(x-p.x, y-p.y); }
    P operator*(T d) const { return P(x*d, y*d); }
    P operator/(T d) const { return P(x/d, y/d); }
    T dot(P p) const { return x*p.x + y*p.y; }
    T cross(P p) const { return x*p.y - y*p.x; }
    T cross(P a, P b) const { return (a-*this).cross(b-*this); }
    T dist2() const { return x*x + y*y; }
    double dist() const { return sqrt((double)dist2()); }
    // angle to x-axis in interval [-pi, pi]
    double angle() const { return atan2(y, x); }
    P unit() const { return *this/dist(); } // makes dist()=1
    P perp() const { return P(-y, x); } // rotates +90 degrees
    P normal() const { return perp().unit(); }
    // returns point rotated 'a' radians ccw around the origin
    P rotate(double a) const {
        return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
    friend ostream& operator<<(ostream& os, P p) {
        return os << "(" << p.x << "," << p.y << ")"; }
};

typedef Point<double> P;

template<class P> bool onSegment(P s, P e, P p) {
    return p.cross(s, e) == 0 && (s - p).dot(e - p) <= 0;
}

double segDist(P& s, P& e, P& p) {
    if (s==e) return (p-s).dist();
    auto d = (e-s).dist2(), t = min(d,max((double)0.0,(p-s).dot(e-s)));
    return ((p-s)*d-(e-s)*t).dist()/d;
}

template<class P>
double lineDist(const P& a, const P& b, const P& p) {
    return (double)(b-a).cross(p-a)/(b-a).dist();
}

template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
    auto d = (e1 - s1).cross(e2 - s2);
    if (d == 0) // if parallel
        return {-(s1.cross(e1, s2) == 0), P(0, 0)};
    auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
    return {1, (s1 * p + e1 * q) / d};
}
P match(P a, P b, P c, P d){
    double dist = (d - c).dist();
    return (b-a).unit() * dist + a;
}
double solve(P a, P b, P c, P d, double len){
    //cout << a << ' ' << b << ' ' << c << ' ' << d << '\n';
    double low = 0; double high = len;
   
    for(int iters = 0; iters < 130; iters++){
        double ds = (high-low)/3.0;
        double m1 = low+ds;
        double m2 = low+2*ds;
        double v1 = (a + b*m1 - (c+d*m1)).dist();
        double v2 = (a + b*m2 - (c+d*m2)).dist();
        if(v1 <= v2){
            high = m2;
        }
        else{
            low = m1;
        }
    }
    //cout << low << ' ' << high << '\n';
    return (a + b*low - (c+d*low)).dist();
}

double solve(vector<P>a, vector<Point<int>>b, int n, double k){
    vector<double>psa(n+1);
    for(int i = 2; i<=n; i++){
        psa[i] = psa[i-1] + (a[i]-a[i-1]).dist();
    }
    double ans = k;
    int r = 1;
    for(int i = 1; i<=n; i++){
        while(r <= n && psa[r] - psa[i] < k){
            r++;
        }
        if(r==n+1){
            break;
        }
        double rq =  k - (psa[r-1] - psa[i]);
        P np = (a[r] - a[r-1]).unit()*rq + a[r-1];
        double querylen = min((a[r]-np).dist(),(a[i+1]-a[i]).dist());
        
        ans = min(ans,solve(a[i],(a[i+1]-a[i]).unit(),np,(a[r]-a[r-1]).unit(),querylen));
        //cout << i << ' ' << r << '\n';
        //cout << np << '\n';
    }
    return ans;
}

double solve2(vector<P>a, vector<Point<int>>b, int n, double k){
    vector<double>psa(n+1);
    for(int i = 2; i<=n; i++){
        psa[i] = psa[i-1] + (a[i]-a[i-1]).dist();
    }
    double ans = k;
    int l = 1;
    for(int i = 1; i<n; i++){
        while(l < i && psa[i]-psa[l] > k){
            l++;
        }
        if(l == 1)continue;
        double rq = k - (psa[i] - psa[l]);
        P np = a[l] + (a[l-1]-a[l]).unit()*rq;
        double querylen = min((a[l]-np).dist(),(a[i+1]-a[i]).dist());
        
        ans = min(ans,solve(np,(a[l]-a[l-1]).unit(),a[i],(a[i+1]-a[i]).unit(),querylen));
    }
    return ans;
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    double s;
    cin >> s;
    int n;
    cin >> n;
    vector<P>a(n+1);
    vector<Point<int>>b(n+1);
    for(int i = 1; i<=n; i++){
        int x,y;
        double dx,dy;
        cin >> x >> y;
        dx = x;
        dy = y;
        b[i] = Point<int>{x,y};
        a[i] = P{dx,dy};
    }
    double ans1 = solve(a,b,n,s);
    //cout << ans1 << '\n' << '\n';
    double ans2 = solve2(a,b,n,s);
    cout << fixed << setprecision(16);
    //cout << ans2 << '\n';
    //cout << "gay\n";
    /*
    line segment i is notated by a[i-1] to a[i]
    */
    reverse(a.begin()+1,a.end());
    ans1 = min(ans1,solve(a,b,n,s));
    //cout << ans1 << '\n' << '\n';
    ans2 = min(ans2,solve2(a,b,n,s));
    cout << min(ans1, ans2) << '\n';
    
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3828kb

input:

5
4
20 0
10 0
10 10
0 10

output:

3.5355339059327376

result:

ok found '3.53553', expected '3.53553', error '0.00000'

Test #2:

score: 0
Accepted
time: 0ms
memory: 4076kb

input:

3.16227766
9
-2 4
2 4
3 1
4 4
5 1
6 4
10 2
6 1
7 4

output:

0.9999999999467538

result:

ok found '1.00000', expected '1.00000', error '0.00000'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3792kb

input:

20
5
9 38
36 16
-5 36
-24 15
30 37

output:

2.2935957603562973

result:

ok found '2.29360', expected '2.29360', error '0.00000'

Test #4:

score: 0
Accepted
time: 1ms
memory: 3772kb

input:

10
40
17 18
12 -5
12 -16
-10 16
7 -15
18 -18
19 15
-19 1
-18 11
-8 -12
-17 -12
5 -12
-15 -8
-10 -10
-4 4
-2 -3
15 17
-2 -9
-13 7
-12 17
15 -3
-19 -14
6 6
14 -5
-10 -15
17 -16
-11 15
9 -6
10 8
19 -1
12 -6
-18 2
14 17
9 -7
-8 -3
7 11
-12 -14
-19 4
-1 15
-17 16

output:

0.0000000000000000

result:

ok found '0.00000', expected '0.00000', error '-0.00000'

Test #5:

score: 0
Accepted
time: 1ms
memory: 4080kb

input:

10
40
10 11
11 15
6 -16
-18 4
10 10
-10 16
-17 11
2 6
-6 -9
17 -7
-7 -5
10 -18
-9 9
-14 10
19 -3
-14 -3
15 -5
-3 16
-10 14
-9 -12
10 -18
10 -4
-9 -11
11 -2
9 2
12 15
2 -17
-8 -16
19 7
-19 -2
-17 7
16 -9
6 -6
8 -18
15 9
17 2
-19 12
-15 -9
1 -15
19 -12

output:

0.3442144373073931

result:

ok found '0.34421', expected '0.34421', error '0.00000'

Test #6:

score: 0
Accepted
time: 30ms
memory: 3896kb

input:

1000
4000
-720538 -681604
667325 347504
-911397 -962007
-264075 -858319
49605 149209
964851 361021
-397274 28661
-460607 -273701
104862 -136807
-803899 -693703
-974 -337735
323678 -209811
-745617 -358684
-984333 603546
722843 -444579
701511 -255784
-676477 -836480
998942 -227888
-502059 -438394
9641...

output:

0.0445047435672661

result:

ok found '0.04450', expected '0.04450', error '0.00000'

Test #7:

score: 0
Accepted
time: 30ms
memory: 3964kb

input:

1000
4000
703 909
500 496
-214 628
914 -44
-330 -238
-1424 -1426
347 1420
332 -1417
877 1678
-1390 819
-921 525
121 -923
-851 -859
512 -151
765 -109
416 -1529
-269 667
475 -234
-708 300
1917 -1935
-909 1342
1141 -696
-272 1295
1908 -1124
-898 -1225
1608 630
-1937 1246
-255 1021
-1005 -1650
-1595 -39...

output:

0.0381857100426788

result:

ok found '0.03819', expected '0.03819', error '0.00000'

Test #8:

score: 0
Accepted
time: 0ms
memory: 3992kb

input:

40
3
100 0
0 100
0 0

output:

15.3073372946035909

result:

ok found '15.30734', expected '15.30734', error '0.00000'

Test #9:

score: 0
Accepted
time: 0ms
memory: 4084kb

input:

48.2842712475
4
-10 -10
10 10
-10 10
10 -10

output:

0.0000000000269401

result:

ok found '0.00000', expected '0.00000', error '0.00000'