现在的位置: 首页 > 综合 > 正文

2015 HNU warm up 12

2019年02月11日 ⁄ 综合 ⁄ 共 11120字 ⁄ 字号 评论关闭

07~11的比赛没怎么做,,真是辛苦sunkang了*^ ^*、、

唉。。可惜花了大把时间竟然没考过科目二,希望23号那一场可以考过> <!


A - Eight Queens

判断给出的解是不是八皇后的合法解。

<span style="font-size:18px;">#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;

char Board[8][10];
bool flag;

bool ok(int x, int y)
{
    if(x >= 8 || x < 0) return false;
    if(y >= 8 || y < 0) return false;
    return true;
}

int main()
{
//    freopen("A.in", "r", stdin);

    while(~scanf("%s", Board[0]))
    {
        flag = true;
        for(int i = 1; i < 8; i++) scanf("%s", Board[i]);

        for(int i = 0; i < 8; i++)
        {
            if(!flag) break;
            bool ck = true;
            for(int j = 0; j < 8; j++)
            {
                if(Board[i][j] == '*')
                {
                    if(!ck) { flag = false; break; }
                    if( ck) ck = false;
                }
            }
        }
        for(int i = 0; i < 8; i++)
        {
            if(!flag) break;
            bool ck = true;
            for(int j = 0; j < 8; j++)
            {
                if(Board[j][i] == '*')
                {
                    if(!ck) { flag = false; break; }
                    if( ck) ck = false;
                }
            }
        }

        for(int i = 0; i < 8; i++)
        {
            int x = i, y = 0;
            bool ck = true;
            for(int j = 0; j < 8 && ok(x, y); j++)
            {
                if(Board[x][y] == '*')
                {
                    if(!ck) { flag = false; break; }
                    if( ck) ck = false;
                }
                x++, y++;
            }
        }
        for(int i = 0; i < 8; i++)
        {
            int x = i, y = 0;
            bool ck = true;
            for(int j = 0; j < 8 && ok(x, y); j++)
            {
                if(Board[y][x] == '*')
                {
                    if(!ck) { flag = false; break; }
                    if( ck) ck = false;
                }
                x++, y++;
            }
        }

        for(int i = 7; i >= 0; i--)
        {
            int x = i, y = 0;
            bool ck = true;
            for(int j = 0; j < 8 && ok(x, y); j++)
            {
                if(Board[x][y] == '*')
                {
                    if(!ck) { flag = false; break; }
                    if( ck) ck = false;
                }
                x--, y++;
            }
        }
        for(int i = 7; i >= 0; i--)
        {
            int x = i, y = 0;
            bool ck = true;
            for(int j = 0; j < 8 && ok(x, y); j++)
            {
                if(Board[y][x] == '*')
                {
                    if(!ck) { flag = false; break; }
                    if( ck) ck = false;
                }
                x--, y++;
            }
        }

        if(flag) puts("valid");
        else puts("invalid");
    }
    return 0;
}</span>


E - Human Cannonball Run

给出起始点和终点,和途中中各个大炮的位置。人跑步的速度是5m/s,大炮上膛加发射至50m(任意方向),需要2s。问从起点到终点,最短需要多长时间。

注意呀!起点必须要跑着去任意一个点。。。

<span style="font-size:18px;">#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
#define MAXN 110
#define eps 1e-10

inline double sig(double x) { return (x > eps) - (x < -eps); };
template <class T> inline T sqr(T a) { return a * a; }
inline double min(double a0, double a1) { return a0 > a1 ? a1 : a0; }

struct Point
{
    double x, y;
    Point() {}
    Point(double _x, double _y): x(_x), y(_y) {}
    void in();
    double dis(const Point &argu) const;

};

void Point::in() { scanf("%lf%lf", &x, &y); }
double Point::dis(const Point &argu) const { return sqrt((x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y)); }

double dis[110][110];
Point pp[110];
double d, t1, t2;

int main()
{
//    freopen("E.in", "r", stdin);

    while(~scanf("%lf%lf%lf%lf", &pp[0].x, &pp[0].y, &pp[1].x, &pp[1].y))
    {
        int n; scanf("%d", &n); n += 2;
        memset(dis, 0x3f, sizeof(dis));
        for(int i = 2; i < n; i++) pp[i].in();

        dis[0][1] = dis[1][0] = pp[0].dis(pp[1]) / 5.0;
        for(int i = 2; i < n; i++)
        {
            double d0 = pp[0].dis(pp[i]), d1 = pp[1].dis(pp[i]);
            double r0 = d0 / 5.0, r1 = d1 / 5.0;
            double c1 = 2 + fabs(r1 - 10.0);
            dis[0][i] = dis[i][0] = r0;
            dis[1][i] = dis[i][1] = min(r1, c1);
        }

        for(int i = 2; i < n; i++) for(int j = 2; j < n; j++)
        {
            double d = pp[i].dis(pp[j]);
            double r = d / 5.0;
            double c = 2 + fabs(r - 10.0);
            dis[i][j] = dis[j][i] = min(r, c);
        }

        for(int k = 0; k < n; k++) for(int i = 0; i < n; i++) for(int j = 0; j < n; j++)
            dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);

        printf("%lf\n", dis[0][1]);
    }
    return 0;
}</span>


G - Pesky Mosquitoes

定长圆覆盖。

<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define LL long long
#define MAXN 110
#define eps 1e-10

const double pi = acos(-1.0);
inline double sig(double x) { return (x > eps) - (x < -eps); };
template <class T> inline T sqr(T a) { return a * a; }

struct Point
{
    double x, y;
    Point() {}
    Point(double _x, double _y): x(_x), y(_y) {}
    void in();
    void out() const;
    double len() const;
    double len2() const;
    double dis(const Point &argu) const;
    double dis2(const Point &argu) const;
    bool operator <(const Point &argu) const;
    Point operator -(const Point &argu) const;
    double operator ^(const Point &argu) const;
    double operator *(const Point &argu) const;
};

struct Segment
{
    Point a, b;
    Segment() {}
    Segment(Point _a, Point _b): a(_a), b(_b) {}
    void in();
    Point d() const;
    void out() const;
    double len() const;
    double len2() const;
    int sgn(const Segment &argu) const;
    bool qrt(const Segment &argu) const;
    double dis2(const Point &argu) const;
    double dis2(const Segment &argu) const;
};

struct Line
{
    Segment l;
    Line() {}
    Line(Segment _l): l(_l) {}
    double dis2(const Point &argu) const;
    double dis2(const Segment &argu) const;
};
inline double Cross(const Point &o, const Point &a, const Point &b) { return (a - o) ^ (b - o); }

void Point::in() { scanf("%lf%lf", &x, &y); }
double Point::len() const { return sqrt(len2()); }
double Point::len2() const { return x * x + y * y; }
void Point::out() const{ printf("%.0lf %.0lf\n", x, y); }
double Point::dis(const Point &argu) const { return sqrt(dis2(argu)); }
double Point::operator ^(const Point &argu) const { return x * argu.y - y * argu.x; }
double Point::operator *(const Point &argu) const { return x * argu.x + y * argu.y; }
Point Point::operator -(const Point &argu) const { return Point(x - argu.x, y - argu.y); }
bool Point::operator <(const Point &argu) const { return sig(x - argu.x) == 0 ? y < argu.y : x < argu.x; }
double Point::dis2(const Point &argu) const { return (x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y); }

void Segment::in() { a.in(), b.in(); }
Point Segment::d() const { return b - a; }
double Segment::len2() const { return d().len2(); }
double Segment::len() const { return sqrt(len2()); }
void Segment::out() const { a.out(), b.out(); }
double Segment::dis2(const Segment &argu) const
{
    if(~sgn(argu)) return 0;
    return min(min(dis2(argu.a), dis2(argu.b)), min(argu.dis2(a), argu.dis2(b)));
}
double Segment::dis2(const Point &argu) const
{
    Point pa = argu - a, pb = argu - b;
    if(sig(d() * pa) <= 0) return pa.len2(); if(sig(d() * pb) >= 0) return pb.len2();
    Line l = Line((*this)); return l.dis2(argu);
}
int Segment::sgn(const Segment &argu) const
{
    if(!qrt(argu)) return -1;
    return sig(Cross(a, b, argu.a)) * sig(Cross(a, b, argu.b)) <= 0 &&
           sig(Cross(argu.a, argu.b, a)) * sig(Cross(argu.a, argu.b, b)) <= 0 ? 1 : -1;
}
//快速排斥实验
bool Segment::qrt(const Segment &argu) const
{
    return min(a.x, b.x) <= max(argu.a.x, argu.b.x) && min(a.y, b.y) <= max(argu.a.y, argu.b.y) &&
           min(argu.a.x, argu.b.x) <= max(a.x, b.x) && min(argu.a.y, argu.b.y) <= max(a.y, b.y);
}

double Line::dis2(const Point &argu) const { return sqr(fabs(l.d() ^ (argu - l.a))) / l.len2(); }
double Line::dis2(const Segment &argu) const
{
    Point v1 = argu.a - l.a, v2 = argu.b - l.b; double d1 = l.d() ^ v1, d2 = l.d() ^ v2;
    return sig(d1) != sig(d2) ? 0 : sqr(min(fabs(d1), fabs(d2))) / l.len2();
}

struct Arc
{
    double ang;
    int in;
    bool operator <(const Arc &argu) const
    {
        return sig(ang - argu.ang) ? (ang < argu.ang) : (in > argu.in);
    }
}arc[MAXN];

int n;
double r;
Point p[MAXN];

int max(int a, int b) { return a > b ? a : b; }

int MAX_CirCle_Cover(double r)
{
    int ret = 0;
    for(int i = 0; i < n; i++)
    {
        int cnt = 0;
        for(int j = 0; j < n; j++)
        {
            if(i == j) continue;
            double d = p[i].dis(p[j]);
            if(sig(d - 2.0 * r) > 0) continue;
            double theta = atan2(p[i].y - p[j].y, p[i].x - p[j].x);
            if(theta < 0) theta += 2 * pi;
            double phi = acos(d / (2.0 * r));
            arc[cnt].ang = theta - phi + 2 * pi; arc[cnt++].in = 1;
            arc[cnt].ang = theta + phi + 2 * pi; arc[cnt++].in = 0;
        }
        sort(arc, arc + cnt);
        int tmp = 0;
        for(int i = 0; i < cnt; i++)
        {
            if(arc[i].in) tmp++;
            else tmp--;
            ret = max(ret, tmp);
        }
    }
    return ret + 1;
}

int work()
{
    scanf("%d%lf", &n, &r);
    r /= 2.0;
    if(sig(r) == 0 || n == 0) return 0;
    for(int i = 0; i < n; i++) p[i].in();
    return MAX_CirCle_Cover(r);
}

int main()
{
//    freopen("G.in", "r", stdin);

    int c; scanf("%d", &c);
    while(c--)
    {
        printf("%d\n", work());
    }
    return 0;
}</span>


K - Yikes ? Bikes!(未完成)

一个胖子要过马路,路上正有一队单车车队经过。

胖子和车队各自的速度恒定。

胖子可以看做一个直径为1m的圆,每个单车可以看做一条长为2m的线段,每个单车之间的间距也是2m。

给出两者速度、给出t=0时,领队的前轮距离胖子所在垂直线的距离、胖子出发的时间;问胖子会抢在第一辆车前过去,还是撞上一辆车,还是在第几辆车后安全通过。

最多只有10辆车。


把胖子的速度转移给单车,这样单车的前段点和后端点的运动路径就是两条向下右斜的平行线。求胖子代表的圆和这些平行的相对位置即可。


胖子的坐标是(0, -0.5)!!!!

然后偷懒,有个很重要的判断没写,居然也过了。。

圆如果在平行线影响范围内,但是是在自行车所代表的的线段的上面(线段也在往下走),那么不能算相撞。

#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
#define MAXN 10010
#define eps 1e-18

//const double pi = acos(-1.0);
inline double sig(double x) { return (x > eps) - (x < -eps); };
template <class T> inline T sqr(T a) { return a * a; }

struct Point
{
    double x, y;
    Point() {}
    Point(double _x, double _y): x(_x), y(_y) {}
    void in();
    void out() const;
    double len() const;
    double len2() const;
    double dis(const Point &argu) const;
    double dis2(const Point &argu) const;
    bool operator <(const Point &argu) const;
    Point operator -(const Point &argu) const;
    double operator ^(const Point &argu) const;
    double operator *(const Point &argu) const;
};

struct Segment
{
    Point a, b;
    Segment() {}
    Segment(Point _a, Point _b): a(_a), b(_b) {}
    void in();
    Point d() const;
    void out() const;
    double len() const;
    double len2() const;
    int sgn(const Segment &argu) const;
    bool qrt(const Segment &argu) const;
    double dis(const Point &argu) const;
    double dis2(const Point &argu) const;
    double dis(const Segment &argu) const;
    double dis2(const Segment &argu) const;
    double operator ^(const Segment &argu) const;
};

struct Line
{
    Segment l;
    Line() {}
    Line(Segment _l): l(_l) {}
    Line(Point _a, Point _b): l(Segment(_a, _b)) {}
    double dis(const Line &argu) const;
    double dis2(const Line &argu) const;
    double dis(const Point &argu) const;
    double dis2(const Point &argu) const;
    double dis(const Segment &argu) const;
    double dis2(const Segment &argu) const;
};
inline double Cross(const Point &o, const Point &a, const Point &b) { return (a - o) ^ (b - o); }

void Point::in() { scanf("%lf%lf", &x, &y); }
double Point::len() const { return sqrt(len2()); }
double Point::len2() const { return x * x + y * y; }
void Point::out() const{ printf("%.4lf %.4lf\n", x, y); }
double Point::dis(const Point &argu) const { return sqrt(dis2(argu)); }
double Point::operator ^(const Point &argu) const { return x * argu.y - y * argu.x; }
double Point::operator *(const Point &argu) const { return x * argu.x + y * argu.y; }
Point Point::operator -(const Point &argu) const { return Point(x - argu.x, y - argu.y); }
bool Point::operator <(const Point &argu) const { return sig(x - argu.x) == 0 ? y < argu.y : x < argu.x; }
double Point::dis2(const Point &argu) const { return (x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y); }

void Segment::in() { a.in(), b.in(); }
Point Segment::d() const { return b - a; }
double Segment::len2() const { return d().len2(); }
double Segment::len() const { return sqrt(len2()); }
void Segment::out() const { a.out(), b.out(); }
double Segment::dis2(const Segment &argu) const
{
    if(~sgn(argu)) return 0;
    return min(min(dis2(argu.a), dis2(argu.b)), min(argu.dis2(a), argu.dis2(b)));
}
double Segment::dis2(const Point &argu) const
{
    Point pa = argu - a, pb = argu - b;
    if(sig(d() * pa) <= 0) return pa.len2(); if(sig(d() * pb) >= 0) return pb.len2();
    Line l = Line((*this)); return l.dis2(argu);
}
int Segment::sgn(const Segment &argu) const
{
    if(!qrt(argu)) return -1;
    return sig(Cross(a, b, argu.a)) * sig(Cross(a, b, argu.b)) <= 0 &&
           sig(Cross(argu.a, argu.b, a)) * sig(Cross(argu.a, argu.b, b)) <= 0 ? 1 : -1;
}
//快速排斥实验
bool Segment::qrt(const Segment &argu) const
{
    return min(a.x, b.x) <= max(argu.a.x, argu.b.x) && min(a.y, b.y) <= max(argu.a.y, argu.b.y) &&
           min(argu.a.x, argu.b.x) <= max(a.x, b.x) && min(argu.a.y, argu.b.y) <= max(a.y, b.y);
}
double Segment::dis(const Point &argu) const { return sqrt(dis2(argu)); }
double Segment::dis(const Segment &argu) const { return sqrt(dis2(argu)); }

double Line::dis(const Point &argu) const { return sqrt(dis2(argu)); }
double Line::dis2(const Point &argu) const { return sqr(fabs(l.d() ^ (argu - l.a))) / l.len2(); }
double Line::dis(const Segment &argu) const { return sqrt(dis2(argu)); }
double Line::dis2(const Segment &argu) const
{
    Point v1 = argu.a - l.a, v2 = argu.b - l.b; double d1 = l.d() ^ v1, d2 = l.d() ^ v2;
    return sig(d1) != sig(d2) ? 0 : sqr(min(fabs(d1), fabs(d2))) / l.len2();
}

//Max's speed,
//speed of the cyclists,
//distance in meters between the front of the lead bicycle,
//start time
double m, b, d, t;
int k;

int main()
{
    int c; scanf("%d", &c);
    Point o(0.0, -0.5);

    while(c--)
    {
        scanf("%lf%lf%lf%lf", &m, &b, &d, &t);

        Point a0(t * b - d,  5.0); Point a1(a0.x + b, a0.y - m);
        Point b0(a0.x - 2.0, 5.0); Point b1(b0.x + b, b0.y - m);
        Line l0(a0, a1), l1(b0, b1);

        double lld = l0.dis(l1.l.a);
        double d0 = l0.dis(o), d1 = l1.dis(o);

        for(int i = 1; i <= 10; i++)
        {
            if(Cross(a0, o, a1) < 0 && sig(d0 - 0.5) > 0)
            {
                if(i == 1) puts("Max beats the first bicycle");
                else printf("Max crosses safely after bicycle %d\n", i - 1);
                break;
            }
            if(sig(lld - d0 - d1) == 0 || sig(d0 - 0.5) <= 0 || sig(d1 - 0.5) <= 0)
            {
                printf("Collision with bicycle %d\n", i);
                break;
            }
            if(i == 10)
            {
                puts("Max crosses safely after bicycle 10");
                break;
            }

            a0.x -= 4.0, a1.x -= 4.0;
            l0 = Line(a0, a1), d0 = l0.dis(o);
            b0.x -= 4.0, b1.x -= 4.0;
            l1 = Line(b0, b1); d1 = l1.dis(o);
        }
    }
    return 0;
}

抱歉!评论已关闭.