SDNU_ACM_ICPC_2020_Winter_Practice_4th

SDNU_ACM_ICPC_2020_Winter_Practice_4th

      • A - The Moving Points HDU - 4717
        • 题解
      • F - TOYS POJ - 2318
        • 题解
      • G - Toy Storage POJ - 2398
        • 题解

A - The Moving Points HDU - 4717

There are N points in total. Every point moves in certain direction and certain speed. We want to know at what time that the largest distance between any two points would be minimum. And also, we require you to calculate that minimum distance. We guarantee that no two points will move in exactly same speed and direction.

题解

两个点之间的距离是一个关于时间 t t t的开口向上的二次函数.
故使用三分来寻找时间 t t t的值
对于每个函数的图像,我们知道时间 t t t是非负的
所以,在正半轴的极小值,要么在极值点,要么在 t = 0 t=0 t=0
故三分右半侧
精度很迷,手写的点结构体,板子套不上不知道为什么

#include 
#include 
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-8;
typedef long long ll;

struct point {
    double x, y;
    double vx, vy;
    point(double _x = 0.0, double _y = 0.0)
        : x(_x)
        , y(_y)
    {
    }
    friend istream& operator>>(istream& in, point& a)
    {
        scanf("%lf%lf%lf%lf", &a.x, &a.y, &a.vx, &a.vy);
        return in;
    }
};
point p[400];
int n;
int bijiao(double x, double y)
{
    if (fabs(x - y) < eps)
        return 0;
    if (x > y)
        return 1;
    return -1;
}
double dis(int x, int y, double t)
{
    point a = point(p[x].x + t * p[x].vx, p[x].y + t * p[x].vy);
    point b = point(p[y].x + t * p[y].vx, p[y].y + t * p[y].vy);
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double check(double t)
{
    double maxx = 0;
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
            maxx = max(maxx, dis(i, j, t));
    return maxx;
}
double find(double l, double r)
{
    double mid, rm;
    while (fabs(l - r) > eps) {
        mid = (l + r) / 2;
        rm = (mid + r) / 2;
        if (check(mid) > check(rm))
            l = mid;
        else
            r = rm;
    }
    return r;
}
int main()
{
    int t;
    cin >> t;
    for (int k = 1; k <= t; k++) {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> p[i];
        double r = find(0, 1e8);
        printf("Case #%d: %.2lf %.2lf\n", k, r, check(r));
    }
    return 0;
}

F - TOYS POJ - 2318

Calculate the number of toys that land in each bin of a partitioned toy box.
Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys in, but John is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for John to find his favorite toys.

John’s parents came up with the following idea. They put cardboard partitions into the box. Even if John keeps throwing his toys into the box, at least toys that get thrown into different bins stay separated. The following diagram shows a top view of an example toy box.
1
For this problem, you are asked to determine how many toys fall into each partition as John throws them into the toy box.

题解

问扔进去n个玩具,每个隔间内各有多少个
SDNU_ACM_ICPC_2020_Winter_Practice_4th_第1张图片
对于线段 A B AB AB,判断点位于其是左侧还是右侧
A C → A B AC\rarr AB ACAB是右旋,那么 A C × A B AC\times AB AC×AB为负
A D → A B AD\rarr AB ADAB是左旋,那么 A D × A B AD\times{AB} AD×AB为正
然后每给定一个点,二分查找即可

#include 
#include 
#include 
#include 
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-12;
typedef long long ll;
const int MAXN = 5010;

typedef struct point vec;
struct point { //点的基本数据结构
    int x, y;
    point(int _x = 0, int _y = 0)
        : x(_x)
        , y(_y)
    {
    }
    double len() //模长
    {
        return sqrt(x * x + y * y);
    }
    vec chuizhi()
    {
        return vec(-y, x);
    }
    int operator*(const point& i_T) const //点积
    {
        return x * i_T.x + y * i_T.y;
    }
    int operator^(const point& i_T) const //叉积
    {
        return x * i_T.y - y * i_T.x;
    }
    point operator*(int u) const
    {
        return point(x * u, y * u);
    }
    bool operator==(const point& i_T) const
    {
        return x == i_T.x && y == i_T.y;
    }
    point operator/(int u) const
    {
        return point(x / u, y / u);
    }
    point operator+(const point& i_T)
    {
        return point(x + i_T.x, y + i_T.y);
    }
    point operator-(const point& i_T)
    {
        return point(x - i_T.x, y - i_T.y);
    }
    friend bool operator<(point a, point b)
    {
        return a.y == b.y ? a.x < b.x : a.y < b.y;
    }
    friend ostream& operator<<(ostream& out, point& a)
    {
        //cout << a.x << ' ' << a.y;
        printf("%d %d", a.x, a.y);
        return out;
    }
    friend istream& operator>>(istream& in, point& a)
    {
        scanf("%d%d", &a.x, &a.y);
        return in;
    }
};
typedef struct Line Segment; //线段Segment
struct Line { //直线
    point a, b;
    Line(point _a = point(), point _b = point())
        : a(_a)
        , b(_b)
    {
    }
    double len()
    {
        return (a - b).len();
    }
    friend istream& operator>>(istream& in, Line& a)
    {
        cin >> a.a >> a.b;
        return in;
    }
    friend ostream& operator<<(ostream& out, Line& a)
    {
        out << a.a << ' ' << a.b;
        return out;
    }
};

int ans[MAXN], n;
Line l[MAXN];
bool cmp(Line li, point p)
{
    return ((p - li.b) ^ (li.a - li.b)) > 0;
}

int main()
{
    //隔板数n, 玩具m,左上角(x1,y1),左下角(x2,y2)
    //每行Ui,Li,指(Ui,y1),(Li,y2)
    int m;
    point a, b;
    while (cin >> n, n) {
        cin >> m >> a >> b;
        l[0] = Line(a, point(a.x, b.y));
        l[n + 1] = Line(point(b.x, a.y), b);
        for (int i = 1; i <= n; i++) {
            point c;
            cin >> c;
            l[i] = Line(point(c.x, a.y), point(c.y, b.y));
        }
        n++;
        for (int i = 1; i <= m; i++) {
            point p;
            cin >> p;
            int pos = lower_bound(l, l + n + 1, p, cmp) - l;
            ans[pos]++;
        }
        for (int i = 1; i <= n; i++) {
            cout << i - 1 << ": " << ans[i] << endl;
            ans[i] = 0;
        }
        cout << endl;
    }
    return 0;
}

G - Toy Storage POJ - 2398

Mom and dad have a problem: their child, Reza, never puts his toys away when he is finished playing with them. They gave Reza a rectangular box to put his toys in. Unfortunately, Reza is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for Reza to find his favorite toys anymore.
Reza’s parents came up with the following idea. They put cardboard partitions into the box. Even if Reza keeps throwing his toys into the box, at least toys that get thrown into different partitions stay separate. The box looks like this from the top:
1
We want for each positive integer t, such that there exists a partition with t toys, determine how many partitions have t, toys.

题解

和上面那个题目类似
区别在于可能会扔出去,nice boy?
只需要把两边的框加上即可

#include 
#include 
#include 
#include 
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-12;
typedef long long ll;
const int MAXN = 5010;

typedef struct point vec;
struct point { //点的基本数据结构
    int x, y;
    point(int _x = 0, int _y = 0)
        : x(_x)
        , y(_y)
    {
    }
    double len() //模长
    {
        return sqrt(x * x + y * y);
    }
    vec chuizhi()
    {
        return vec(-y, x);
    }
    int operator*(const point& i_T) const //点积
    {
        return x * i_T.x + y * i_T.y;
    }
    int operator^(const point& i_T) const //叉积
    {
        return x * i_T.y - y * i_T.x;
    }
    point operator*(int u) const
    {
        return point(x * u, y * u);
    }
    bool operator==(const point& i_T) const
    {
        return x == i_T.x && y == i_T.y;
    }
    point operator/(int u) const
    {
        return point(x / u, y / u);
    }
    point operator+(const point& i_T)
    {
        return point(x + i_T.x, y + i_T.y);
    }
    point operator-(const point& i_T)
    {
        return point(x - i_T.x, y - i_T.y);
    }
    friend bool operator<(point a, point b)
    {
        return a.y == b.y ? a.x < b.x : a.y < b.y;
    }
    friend ostream& operator<<(ostream& out, point& a)
    {
        //cout << a.x << ' ' << a.y;
        printf("%d %d", a.x, a.y);
        return out;
    }
    friend istream& operator>>(istream& in, point& a)
    {
        scanf("%d%d", &a.x, &a.y);
        return in;
    }
};
typedef struct Line Segment; //线段Segment
struct Line { //直线
    point a, b;
    Line(point _a = point(), point _b = point())
        : a(_a)
        , b(_b)
    {
    }
    double len()
    {
        return (a - b).len();
    }
    friend istream& operator>>(istream& in, Line& a)
    {
        cin >> a.a >> a.b;
        return in;
    }
    friend ostream& operator<<(ostream& out, Line& a)
    {
        out << a.a << ' ' << a.b;
        return out;
    }
    bool operator<(const Line x)const
    {
        return a < x.a;
    }
};

int ans[MAXN], n, sum[MAXN];
Line l[MAXN];
bool cmp(Line li, point p)
{
    return ((p - li.b) ^ (li.a - li.b)) > 0;
}

int main()
{
    //隔板数n, 玩具m,左上角(x1,y1),左下角(x2,y2)
    //每行Ui,Li,指(Ui,y1),(Li,y2)
    int m;
    point a, b;
    while (cin >> n, n) {
        cin >> m >> a >> b;
        l[0] = Line(a, point(a.x, b.y));
        l[n + 1] = Line(point(b.x, a.y), b);
        for (int i = 1; i <= n; i++) {
            point c;
            cin >> c;
            l[i] = Line(point(c.x, a.y), point(c.y, b.y));
        }
        sort(l + 1, l + n + 1);
        n++;
        for (int i = 1; i <= m; i++) {
            point p;
            cin >> p;
            int pos = lower_bound(l, l + n + 1, p, cmp) - l;
            ans[pos]++;
        }
        cout << "Box" << endl;
        for (int i = 1; i <= n; i++){
            sum[ans[i]]++;
            ans[i] = 0;
        }
        for (int i = 1; i <= 1000; i++)
            if (sum[i]) {
                cout << i << ": " << sum[i] << endl;
                sum[i] = 0;
            }
    }
    return 0;
}

你可能感兴趣的:(QLU_ACM比赛)