SDNU_ACM_ICPC_2020_Winter_Practice_4th

微笑、不失礼 提交于 2020-02-10 21:23:24

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.

题解

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

#include <cmath>
#include <iostream>
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个玩具,每个隔间内各有多少个
2
对于线段ABAB,判断点位于其是左侧还是右侧
ACABAC\rarr AB是右旋,那么AC×ABAC\times AB为负
ADABAD\rarr AB是左旋,那么AD×ABAD\times{AB}为正
然后每给定一个点,二分查找即可

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
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 <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!