2020 Multi-University Training Contest 7

Animism
Bitwise Xor
Counting
Decision
Expectation
Flower

Game

官方题解
2020 Multi-University Training Contest 7_第1张图片
但是没看懂……

#include 
using namespace std;
typedef long long ll;
const int N = 2e3 + 10;
int n;

struct Point {
     
    ll x, y;

    void read() {
     
        cin >> x >> y;
    }
} p[N];

ll getDist(Point a, Point b) {
     
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

struct Edge {
     
    int u, v;
    ll dis;

    bool operator<(const Edge b) const {
     
        return dis > b.dis;
    }
};

int vis[N];

int main() {
     
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int T;
    cin >> T;
    for (int cs = 1; cs <= T; cs++) {
     

        cin >> n;
        for (int i = 1; i <= n; i++) {
     
            vis[i] = 0;
            p[i].read();
        }

        vector<Edge> edge;
        for (int i = 1; i <= n; i++) {
     
            for (int j = i + 1; j <= n; j++) {
     
                edge.push_back({
     i, j, getDist(p[i], p[j])});
            }
        }
        sort(edge.begin(), edge.end());

        for (auto e:edge) {
     
            if (!vis[e.u] && !vis[e.v]) {
     
                vis[e.u] = vis[e.v] = 1;
            }
        }
        if (vis[1]) {
     
            cout << "YES" << endl;
        } else {
     
            cout << "NO" << endl;
        }
    }
    return 0;
}

Heart

Increasing and Decreasing

#include 
using namespace std;
const int N = 1e6 + 10;
int n, k;
int b[N];

int main() {
     
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T, x, y;
    cin >> T;
    while (T--) {
     
        cin >> n >> x >> y;
        if (y == 1) {
     
            if (x == n) {
     
                cout << "YES" << endl;
                for (int i = 1; i <= n; i++) {
     
                    cout << i << (i == n ? "\n" : " ");
                }
            } else {
     
                cout << "NO" << endl;
            }
        } else {
     
            int a = (n - x) / (y - 1);
            if (a >= 1 && x - a <= n - a * y && x - a >= 0) {
     
                // init
                for (int i = 1; i <= n; i++) {
     
                    b[i] = 0;
                }

                int l = 0, r = n;
                for (int i = 1, lim = x - a - 1; i <= lim; i++) {
     
                    b[i] = i;
                }
                l = x - a;

                k = n - y + 1;
                for (int i = 1; i <= a; i++, k -= y) {
     
                    for (int j = k; j < k + y; j++) {
     
                        b[j] = r--;
                    }
                }

                for (int i = l; l <= r; i++) {
     
                    b[i] = r--;
                }

                int flag = 0;
                for (int i = 1; i <= n; i++) {
     
                    if (b[i] == 0) {
     
                        cout << "NO" << endl;
                        flag = 1;
                        break;
                    }
                }

                if (!flag) {
     
                    cout << "YES" << endl;
                    for (int i = 1; i <= n; i++) {
     
                        cout << b[i] << (i == n ? "\n" : " ");
                    }
                }
                
            } else {
     
                cout << "NO" << endl;
            }
        }
    }
    return 0;
}

Jogging

[markov系列1]从马尔可夫链看矩阵的乘法
[markov系列2]马尔可夫链中的期望问题

第3题的2/7的由来:

经发现能够到达的点只有3个:1号点(18,8)2号点(18,9) 3号点(18,10)

观察发现,虽然不停留在原地的概率为 z z + 1 \cfrac{z}{z+1} z+1z,但是从该点到达其他点的概率都是 1 z + 1 \cfrac{1}{z+1} z+11

然后可以由此画出马尔科夫链↓
2020 Multi-University Training Contest 7_第2张图片
v t i v^i_t vti 表示第 t t t 步到达 i i i 点的概率

x t x_t xt 为第 t t t 步到达各个点的概率向量矩阵,即
x t = [ v t 1 v t 2 v t 3 ] x_t=\begin{bmatrix} v^1_t & v^2_t &v^3_t \end{bmatrix} xt=[vt1vt2vt3]

则刚开始第0步时: x 0 = [ 1 0 0 ] x_0=\begin{bmatrix}1 & 0 &0\end{bmatrix} x0=[100]

因为每走一步都有
v t + 1 i = p i 1 × v t 1 + p i 2 × v t 2 + p i 3 × v t 3 v^i_{t+1}=p_{i1}\times v^1_{t}+p_{i2}\times v^2_{t}+p_{i3}\times v^3_{t} vt+1i=pi1×vt1+pi2×vt2+pi3×vt3

其中 p i j p_{ij} pij 表示 j j j 点到 i i i 点的概率

用矩阵乘法表示
v t + 1 i = [ p i 1 p i 2 p i 3 ] [ v t 1 v t 2 v t 3 ] v^i_{t+1}=\begin{bmatrix} p_{i1} & p_{i2} & p_{i3}\end{bmatrix}\begin{bmatrix} v^1_t\\v^2_t\\v^3_t\end{bmatrix} vt+1i=[pi1pi2pi3]vt1vt2vt3

根据上图画出概率矩阵
P = [ p 11 p 12 p 13 p 21 p 22 p 23 p 31 p 32 p 33 ] P=\begin{bmatrix} p_{11} &p_{12} & p_{13} \\ p_{21} &p_{22} & p_{23} \\ p_{31} &p_{32} & p_{33} \end{bmatrix} P=p11p21p31p12p22p32p13p23p33

x t = P × x t − 1 x_t=P\times x_{t-1} xt=P×xt1,即
[ v t 1 v t 2 v t 3 ] = [ p 11 p 12 p 13 p 21 p 22 p 23 p 31 p 32 p 33 ] × [ v t − 1 1 v t − 1 2 v t − 1 3 ] \begin{bmatrix} v^1_t\\v^2_t\\v^3_t\end{bmatrix}=\begin{bmatrix} p_{11} &p_{12} & p_{13} \\ p_{21} &p_{22} & p_{23} \\ p_{31} &p_{32} & p_{33} \end{bmatrix}\times \begin{bmatrix} v^1_{t-1} \\v^2_{t-1}\\v^3_{t-1}\end{bmatrix} vt1vt2vt3=p11p21p31p12p22p32p13p23p33×vt11vt12vt13

通过 x t = P t × x 0 x_t=P^t\times x_0 xt=Pt×x0,显然可以搞出
[ v t 1 v t 2 v t 3 ] = [ 1 2 1 3 0 1 2 1 3 1 2 0 1 3 1 2 ] t × [ 1 0 0 ] \begin{bmatrix} v^1_t\\v^2_t\\v^3_t\end{bmatrix}=\begin{bmatrix} \frac{1}{2} & \frac{1}{3} & 0\\ \frac{1}{2} & \frac{1}{3} & \frac{1}{2}\\ 0 &\frac{1}{3} & \frac{1}{2} \end{bmatrix}^t\times \begin{bmatrix}1 \\ 0\\0\end{bmatrix} vt1vt2vt3=2121031313102121t×100

python跑重复几次矩阵乘法就出来了…

#include 
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
const int dir[8][2] = {
     1, 0, 0, 1, -1, 0, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
ll x, y;
queue<pll> q;
int vis[6005][6005];
ll xbase, ybase;
ll a, b;

int main() {
     
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while (T--) {
     
        // init
        while (!q.empty())q.pop();
        for (int i = 1; i <= 200; i++) {
     
            for (int j = 1; j <= 200; j++) {
     
                vis[i][j] = 0;
            }
        }

        cin >> x >> y;

        xbase = x - 100;
        x = 100;
        ybase = y - 100;
        y = 100;

        int flag = 0;

        a = 1;// 呆在原地不动
        b = 0;
        q.push({
     x, y});
        while (!q.empty()) {
     
            pll u = q.front();
            q.pop();

            if (u.first + xbase == u.second + ybase) {
     //对角线
                flag = 1;
                break;
            }
            if (vis[u.first][u.second]) continue;
            vis[u.first][u.second] = 1;

            int cnt = 0;
            for (int i = 0; i < 8; i++) {
     
                ll dx = u.first + dir[i][0];
                ll dy = u.second + dir[i][1];
                if ((dx + xbase > 0) && (dy + ybase > 0) && __gcd(dx + xbase, dy + ybase) != 1) {
     
                    if (dx == 100 && dy == 100) a++;//回到起点
                    cnt++; // 到达其他点
                    if (!vis[dx][dy])
                        q.push({
     dx, dy});
                }
            }
            b += cnt + 1;//包括呆在原地不动
        }

        if (flag) {
     
            cout << "0/1" << endl;
        } else {
     
            ll g = __gcd(a, b);
            a /= g;
            b /= g;
            cout << a << "/" << b << endl;
        }
    }
    return 0;
}

Kcats

你可能感兴趣的:(多校)