0

uva オンライン ジャッジ ( http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=1204 ) の問題 10263 (Railway) を解決していて、コードの間違った回答を得ていました。友人 (問題を解決して受け入れられた) と話し合った後、彼は私のコードを見て、彼のコードと非常によく似ていました (たとえば、私たちはチームとしてトレーニングしているため、ジオメトリ関数はすべて同じでした)。 ICPC と同じコード ライブラリを使用する)。

それで、一度に 1 つの変更を試みて何が問題なのかを調べ始めた後、この奇妙な動作を見つけました。

私の最初のコード(間違った答えを得た)はこれです:

#include <iostream>
#include <cmath>
#include <cstdio>
#include <limits>
#define EPS 1e-9
using namespace std;

struct point {
    double x, y;
    point(double _x, double _y) { x = _x, y = _y; } //EDITED
    point() { x = 0.0, y = 0.0; }
};

double dist(point p1, point p2) {
    return hypot(p1.x - p2.x, p1.y - p2.y); 
}

double distToLine(point p, point A, point B, point *c) {
    double scale = (double) ((p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y)) / ((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y));
    c->x = A.x + scale * (B.x - A.x);
    c->y = A.y + scale * (B.y - A.y);
    return dist(p, *c); 
}

double distToLineSegment(point p, point A, point B, point* c) {
    if ((B.x-A.x) * (p.x-A.x) + (B.y-A.y) * (p.y-A.y) < EPS) {
        c->x = A.x; c->y = A.y;
        return dist(p, A); 
    }
    if ((A.x-B.x) * (p.x-B.x) + (A.y-B.y) * (p.y-B.y) < EPS) {
        c->x = B.x; c->y = B.y; 
        return dist(p, B); 
    } 
    return distToLine(p, A, B, c); 
}

int main() {
    int Mx, My;
    while (cin >> Mx) {
        int N, x, y;
        cin >> My >> N;

        point A, B, aux, res, M(Mx, My);
        double dres = numeric_limits<double>::infinity(), d;

        cin >> x >> y;
        A = point(x,y);

        for (int i=0; i<N; i++) {
            cin >> x >> y;
            B = point(x,y);

            d = distToLineSegment(M, A, B, &aux);
            if (d < dres) {
                dres = d;
                res = aux;
            }
            A = B;
        }


        printf("%.4f\n%.4f\n",res.x,res.y);
    }
}

さて、この行を変更した後:

int Mx, My;
    while (cin >> Mx) {
        int N, x, y;
        cin >> My >> N;

        point A, B, aux, res, M(Mx, My);

point M;
    while (cin >> M.x) {
        int N, x, y;
        cin >> M.y >> N;

        point A, B, aux, res;

私の解決策は受け入れられました。int 値を読み取ってからポイントを作成する際の問題を理解できる人はいますか? このコードはどのような原因で「誤動作」し、他のコードとは異なる応答を生成する可能性がありますか? また、なぜ「M」が唯一の問題だったのかについてのアイデアはありますか? (以前と同じように「A」と「B」を読み続けましたが、答えには影響しませんでした。「M」の読み方だけを変更する必要がありました)。

何が起こっているのかを理解するのに役立つヒントがあれば、大歓迎です!


編集:「間違ったバージョンに戻す」ときにコンストラクターを間違って書きました、ごめんなさい。

4

1 に答える 1

1

違いは、@ jhonchen902 がコメントで示唆していることです。この問題では、出力は小数点以下 4 桁の浮動小数点数でなければならないと指定されています。

最初のバージョンでは、整数を使用しています。

于 2013-07-17T10:47:34.127 に答える