UVa LA 4253 & UVa 1421 Archery enumeration, state cuts, oj wrong item difficulty: 1

topic

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4167

 

The meaning of problems

An n + 1 line segments parallel to the x-axis, the lowermost segment is [0, w], standing on a point on the bottom of the 0-th line segments, asked whether or not a straight line through that point is also achieved by the above n of line segments. 2 <= n <= 5000,2 <= w <= 1e7, n + 1 to ensure that line segments have different height. Article highest segment 0 to segment height difference (y-coordinate difference) does not exceed n, each segment of data to ensure that different heights. For the i th segment, the left and right end abscissa Li, Ri necessarily satisfying 0 <= Li <Ri <= W. The i th segment height Di satisfies 0 <= Di <= W. Li, Ri, Di are integers, so less accuracy problems.

 

Thinking

Think will think straight two-point or point inclined. Here a two-point will TLE. It can only be a point inclined, and enumerate the slope is not a good practice. Thus, it can be enumerated on a straight line, then the slope of view there is no straight line with the results. Since the straight line can be translated, so the total elapsed for simultaneously be translated to the i-th line segment and a left end point where the k-th segment of the right point. Thus we only need to enumerate the left end of the n + 1 line segments.

For the i-th segment of the left end point (Li, Di), if there is a through (Li, Di) of the straight line through all of the n + 1 line segments, may be output "YES", otherwise, the next segment will continue to enumerate the left point. Alternatively it can be said, such as (Li, Di), the presence of the slope k (k possibly infinite) such that the straight line through all of the corresponding n + 1 line segments, it is intended to meet the problem

Since the line segment is parallel to the x-axis, the case is not generated across the x-axis, then each peptide can maintain a set of possible corresponding slope, and if these sets of non-empty set, then there results for the there is a straight line.

However, there is a case to directly maintain the slope over 90 degrees, and therefore, can be established in the polar coordinate system (Li, Di) as the center, the angle corresponding to the maintenance segment. If higher than Di, the corresponding interval (Ri, Di) corresponds to a polar angle (Li, Di) corresponds to a polar angle of the closed section. If less than Di, that is below the x-axis, always be converted without loss of significance corresponding to a direction opposite to the x-axis direction interval.

 

Comments:

1. Note that if the scanf ( "% d% d", R, & n) == 2 as a determination condition, will wa, which is generally redundant because test data

2. start enumerating endpoint of two segments <Left, Left> <Left, Right>, <right, left>, <right, right> four cases, it has been TLE. However, because it will surely be translated to another point both left right point, so a direct enumeration Traverse the left or right end point is enough

3. Accuracy down without special attention

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef pair<int, int> Pair;
typedef long long ll;
const int MAXN = 5e3 + 4;
const double pie = acos(-1.0);
int n;
int D[MAXN];
int L[MAXN];
int R[MAXN];
bool simplecheck() {
    int mnX = 0;
    int mxX = R[0];
    for (int i = 0; i <= n; i++) {
        mnX = max(mnX, L[i]);
        mxX = min(mxX, R[i]);
    }
    return mnX <= mxX;

}

double getK(int x0, int x1, int y0, int y1) {
    return (y1 - y0) * 1.0 / (x1 - x0);
}

double getAng(int x0, int x1, int y0, int y1) {
    if (x0 == x1)return pie / 2;
    double ang = atan(getK(x0, x1, y0, y1));
    if (ang < 0)return ang + pie;
    return ang;
}

void getAngInterval(int x0, int y0, int i, double& a0, double& a1) {
    if (D[i] == y0) {
        a0 = 0;
        a1 = pie;
    }
    else if (D[i] > y0) {
        a0 = getAng(x0, R[i], y0, D[i]);
        a1 = getAng(x0, L[i], y0, D[i]);
    }
    else {
        a0 = getAng(x0, L[i], y0, D[i]);
        a1 = getAng(x0, R[i], y0, D[i]);
    }
}
int main() {
    int T;
    freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
    freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
    scanf("%d", &T);
    //cin >> T;
    for (int ti = 1; ti <= T; ti++) {
        scanf("%d%d", R, &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d%d%d", D + i, L + i, R + i);
        }
        bool fl = simplecheck();
        if (!fl) {
            for (int i = 0; i <= n; i++) {
                double amn = 0, amx = pie;
                bool ok = true;
                for (int j = 0; j <= n && ok; j++) {
                    double amnnow, amxnow;
                    getAngInterval(L[i], D[i], j, amnnow, amxnow);
                    if (amnnow > amx) {
                        ok = false;
                        break;
                    }
                    if (amxnow < amn) {
                        ok = false;
                        break;
                    }
                    amn = max(amn, amnnow);
                    amx = min(amx, amxnow); 
                    //printf("From (%d, %d) to (%d, %d)->(%d, %d), ang [%.2f, %.2f], Overall [%.2f, %.2f]\n", L[i], D[i], L[j], D[j], R[j], D[j], amnnow * 180.0 / pie, amxnow * 180.0 / pie, amn * 180.0 / pie, amx * 180.0 / pie);

                }
                if (ok) {
                    fl = true;
                    break;
                }
            }
        }
        if (fl) {
            puts("YES");
        }
        else puts("NO");
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/xuesu/p/10993209.html