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

2015 HNU warm up 03

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

这一套题为2013年长沙网络赛。


A - So Easy!

三张图说明一切。。。

1.

2.

3.

但是第三张有个地方错了,的幂应该是n-2。(图来自网络,如有冒犯立刻删除)

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define N 2
#define MAXN 500
#define OT printf
#define LL long long
#define INF 0x7f7f7f7f
#define RUN(x) freopen(#x, "r", stdin);
#define REP(i, n) for(i = 0; i < n; i++)
#define FOR(i, s, e) for(i = s; i <= e; i++)
#define DWN(i, s, e) for(i = e; i >= s; i--)

LL a, b;
int n, mod;

struct Matrix
{
    int mat[N][N], r, c;
    Matrix() {}
    void clr() { memset(mat, 0, sizeof(mat)); }
    Matrix E()
    {
        Matrix e;
        e.clr();
        int i;
        REP(i, N) e.mat[i][i] = 1;
        return e;
    }
    Matrix operator *(const Matrix &argu)
    {
        int i, j, k;
        Matrix ret; ret.clr();
        REP(i, N) REP(j, N) REP(k, N)
        {
            ret.mat[i][j] += mat[i][k] * argu.mat[k][j];
            ret.mat[i][j] %= mod;
        }
        return ret;
    }
    Matrix Pow(int n)
    {
        Matrix p = (*this), res = E();
        while(n)
        {
            if(n & 1) res = res * p;
            p = p * p;
            n >>= 1;
        }
        return res;
    }
    void out()
    {
        int i, j;
        REP(i, N)
        {
            REP(j, N) OT("%d ", mat[i][j]);
            puts("");
        }
    }
};

Matrix p;

int main()
{
//    RUN(A.in);

    while(~scanf("%I64d%I64d%d%d", &a, &b, &n, &mod))
    {
        if(n == 1) { OT("%I64d\n", 2 * a % mod); continue; }
        p.mat[0][0] = 2 * a % mod; p.mat[0][1] = (b - a * a % mod + mod) % mod;
        p.mat[1][0] = 1; p.mat[1][1] = 0;
        Matrix k = p.Pow(n - 2);
//        k.out();
        LL ans = ((b + a * a % mod) % mod * 2 * k.mat[0][0] % mod + 2 * a * k.mat[0][1] % mod) % mod;
        OT("%I64d\n", ans);
    }
    return 0;
}

C - Brilliant Programmers Show

给出黑客们的初始排名,排名相邻的黑客间可以互相挑战,低位向高位挑战成功则两人名次调换,否则不变。

按照初始排名给出每个黑客挑战成功的次数,问谁是最后的冠军。

1.首先挑战成功次数最多的那个肯定是冠军;

2.冠军打败了在他前面所有的人;

3.冠军会打败后面向他挑战的所有人;

4.后来者能向冠军挑战,也必须打败他们之间的所有人。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define MAXN 1000100
#define LL __int64

template <class T>
inline int RD(T &x)
{
        x = 0;
        char ch = getchar();
        while(!isdigit(ch)) { ch = getchar(); if(ch == EOF) return 0; }
        while(isdigit(ch)) { x *= 10; x += ch - '0'; ch = getchar(); }
        return 1;
}

int n;
LL a[MAXN];

void solve()
{
    LL l = 0, r = 0, tmp = 0;
    int p;

    for(int i = 0; i < n; i++)
    {
        if(a[i] >= l) p = i;
        l += 1 + a[i];
    }
    l = 0;
    for(int i = 0; i < p; i++) l += 1 + a[i];
    for(int i = p + 1; i < n; i++)
    {
        r += (0 > a[i] - tmp ? 0 : a[i] - tmp);
        tmp += (a[i] <= tmp);
    }
    if(a[p] > r + l) puts("Bad Rescue");
    else if(a[p] == r + l) printf("%d\n", p + 1);
    else puts("Unknown");
}

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

    int t = 0;
    while(~scanf("%d", &n))
    {
        t++;
        if(t >= 40) continue;
        for(int i = 0; i < n; i++) RD(a[i]);
        solve();
    }
    return 0;
}

I - Throw the Stones
加入哪一个点时,凸包体积增量最大。

注意重点,所有点共线,所有点共面的情况。

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

inline int sig(double x)
{
    return (x > eps) - (x < -eps);
}

typedef struct Point
{
        double x, y, z;
        Point(double _x = 0.0, double _y = 0.0, double _z = 0.0):
                x(_x), y(_y), z(_z) {}

        double dis(const Point &argu) const
        {
            return sqrt((x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y) + (z - argu.z) * (z - argu.z));
        }
        Point operator ^(const Point &argu) const
        {
            return Point(y * argu.z - z * argu.y, z * argu.x - x * argu.z, x * argu.y - y * argu.x);
        }
        double operator *(const Point &argu) const
        {
            return x * argu.x + y * argu.y + z * argu.z;
        }
        Point operator +(const Point &argu) const
        {
            return Point(x + argu.x, y + argu.y, z + argu.z);
        }
        Point operator -(const Point &argu) const
        {
            return Point(x - argu.x, y - argu.y, z - argu.z);
        }
        double len() const
        {
            return sqrt(x * x + y * y + z * z);
        }
        double dis_line(Point &a0, Point &a1)
        {
            return ((*this - a0) ^ (a1 - a0)).len() / (a1 - a0).len();
        }
        double dis_seg(Point &a0, Point &a1)
        {
            if(sig((*this - a0) * (a1 - a0)) >= 0 && sig((*this - a1) * (a0 - a1)) >= 0) return dis_line(a0, a1);
            return min(dis(a0), dis(a1));
        }
        double V6(Point a0, Point a1, Point a2)
        {
            return (((a0 - *this) ^ (a1 - *this)) * (a2 - *this));
        }
        int side(const Point &a0, const Point &a1, const Point &a2) { return sig(V6(a0, a1, a2)); }
        void in()
        {
            scanf("%lf%lf%lf", &x, &y, &z);
        }
        void out()
        {
            printf("%.10lf %.10lf %.10lf\n", x, y, z);
        }
}Vector;

Point p[MAXN];

struct Face
{
    int a, b, c;
    bool flag;
    Face() {}
    Face(int a, int b, int c, bool flag): a(a), b(b), c(c), flag(flag) {}
    bool cansee(const Point &argu)
    {
        return p[a].side(p[b], p[c], argu) > 0;
    }
};

Face fac[MAXN * 10];

struct Hull
{
    double diffv;
    int cnt, mat[MAXN][MAXN];

    void init()
    {
        cnt = 0;
        for(int i = 0; i < 4; ++i)
        {
            Face temp = Face((i + 1) % 4, (i + 2) % 4, (i + 3) % 4, true);
            if(temp.cansee(p[i])) swap(temp.a, temp.c);
            mat[temp.a][temp.b] = mat[temp.b][temp.c] = mat[temp.c][temp.a] = cnt;
            fac[cnt++] = temp;
        }
    }

    void deal(int k, int a, int b)
    {
        int f = mat[a][b];
        if(fac[f].flag)
        {
            if(fac[f].cansee(p[k])) dfs(k, f);
            else
            {
                mat[b][a] = mat[a][k] = mat[k][b] = cnt;
                fac[cnt++] = Face(b, a, k, true);
            }
        }
    }

    void dfs(int k, int f)
    {
        diffv += p[fac[f].a].V6(p[fac[f].b], p[fac[f].c], p[k]);
        fac[f].flag = false;
        deal(k, fac[f].b, fac[f].a);
        deal(k, fac[f].c, fac[f].b);
        deal(k, fac[f].a, fac[f].c);
    }

    double update(int k)
    {
        diffv = 0;
        for(int i = 0; i < cnt; ++i)
        {
            if(!fac[i].flag || !fac[i].cansee(p[k])) continue;
            dfs(k, i);
            break;
        }
        return diffv;
    }

    double vol()
    {
        double res = 0;
        for(int i = 0; i < cnt; ++i) if(fac[i].flag)
            res -= p[fac[i].a].V6(p[fac[i].b], p[fac[i].c], Point(0, 0, 0));
        return res;
    }
}thrower;

int n, k;

void work()
{
    int king = 0;
    double ans = 0;
    for(int i = 1, tag = 1; i < n; ++i)
    {
        if(tag == 1)
        {
            tag += sig((p[0] - p[i]).len());
            if(tag > 1) swap(p[1], p[i]);
        }
        else if(tag == 2)
        {
            tag += sig(((p[1] - p[0]) ^ (p[i] - p[0])).len());
            if(tag > 2) swap(p[2], p[i]);
        }
        else if(tag == 3)
        {
            tag += (sig(p[0].V6(p[1], p[2], p[i])) != 0);
            if(tag > 3)
            {
                swap(p[3], p[i]);
                thrower.init();
                for(int j = 4; j <= i; ++j) thrower.update(j);
                king = i, ans = thrower.vol();
            }
        }
        else
        {
            double v = thrower.update(i);
            if(sig(v - ans) > 0)
            {
                ans = v;
                king = i;
            }
        }
    }
    printf("%d %.2f\n", king + 1, ans / 6.0);
}

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

    k = 0;
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 0; i < n; ++i) p[i].in();
        printf("Case #%d:\n", ++k);
        work();
    }
}

【上篇】
【下篇】

抱歉!评论已关闭.