SDNU_ACM_ICPC_2020_Winter_Practice_4th

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 <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
对于线段 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 <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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值