zoukankan      html  css  js  c++  java
  • Namomo Test Round 1 题解

    倾情打造的Namomo上线啦

    A

    (b − 1) * a ≥ n − 1 输出 Yes,

    假设最小的数排在最末尾,则每次排序上升(冒泡) b - 1 个数字

    最底最小数都冒泡到了最顶部, 那其他数早就冒泡好了

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=(b);++i)
    #define per(i,a,b) for(int i=a;i>=(b);--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
    
    const int N = 1e5 + 5;
    
    ll n, m, _, k;
    
    int main() 
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_) 
        {
            ll a, b; cin >> n >> a >> b;
            if (n - 1 <= (b - 1) * a) cout << "Yes
    ";
            else cout << "No
    ";
        }
        return 0;
    }
    

    B

    不开ll见祖宗

    对于每次不知情, 帽子 i 被选择的概率为 x = (n - 2) / n, 被选择的概率为 y = 1 - (n - 2) / n = 2 / n

    假设当前帽子 i 有的概率为 a, 则此次不知情的操作后 概率为 a * x + y * (1 - a) / n

    我们变换一下 y = y / n, z = x - y, 则

    a * x + y * (1 - a) / n = a * z + y

    那多次不知情操作呢?

    (((a * z + y) * z + y) * z + y) ... = a * z ^ k + y * z ^ (k - 1) + y * z ^ (k - 2) + ... + y * z ^ 0

    发现没有, 我们可以预处理 z的n次方 和 y * z ^ k 的前缀和, 那么多次操作就是 O(1)

    然后我们还发现, 只有一只帽子的概率最大(最开始这个帽子编号为 1), 其他帽子概率相等,

    所以我们对于知情操作, 纪录哪个帽子概率最大即可, 那我们就只用保存两个答案即可

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=(b);++i)
    #define per(i,a,b) for(int i=a;i>=(b);--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
    
    const int N = 100005;
    const int mod = 998244353;
    
    int n, m, _, k, now;
    ll ans[2], s[N], g[N], x, y, z;
    
    ll quick(ll k1, ll k2)
    {
        ll k3 = 1;
        for (; k2; k2 >>= 1, k1 = k1 * k1 % mod)
            if (k2 & 1) k3 = 1ll * k3 * k1 % mod;
        return k3;
    }
    
    ll get(ll a, ll b)
    {
        return a * quick(b, mod - 2) % mod;
    }
    
    void work(int c)
    {
        if (c == 0) return;
        rep(i, 0, 1) ans[i] =  (ans[i] * g[c] % mod + s[c - 1]) % mod;
    }
    
    void init()
    {
        ans[1] = 0;
        now = ans[0] = g[0] = 1;
    
        x = get(n - 2, n), y = get(2, (ll)n * (n - 1) % mod), z = (x - y + mod) % mod;
    
        s[0] = y; 
        rep(i, 1, m) g[i] = g[i - 1] * z % mod, s[i] = (s[i - 1] + g[i] * y % mod) % mod;
    }
    
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> n >> m >> k; now = 1;
    
            if (n == 2) { cout << (m % 2 == 0 ? "1 0
    " : "0 1
    "); continue; }
    
            init(); work(m - k);
    
            rep(i, 1, k)
            {
                int a, b, c; cin >> a >> b >> c;
    
                if (c == now) now = b;
                else if (b == now) now = c;
            }
    
            rep(i, 1, n) cout << (now == i ? ans[0] : ans[1]) << ' ';
            cout << endl;
        }
        return 0;
    }
    

    C

    直接丢官方题解思路

    给出一个矩阵快速幂的做法。

    首先当 x=k 时,满足 y-l≡2或4(mod6)时答案为1,否则答案为0。下面讨论 x<k:

    小沃沃路线分为:

    从标号为 x 的正六边形的 y 号点出发,走到标号为 x 的正六边形的 1/2 号点。

    从标号为 x 的正六边形的 1/2 号点出发,走到从标号为 x+1 的正六边形的 1/2 号点。

    ...

    从标号为 k-2 的正六边形的 1/2 号点出发,走到从标号为 k-1 的正六边形的 1/2 号点。

    从标号为 k−1 的正六边形的 1/2 号点出发,走到从标号为 k 的正六边形的 l 号点。

    设一个正六边形中小沃沃的四种状态:位于 1 号点方向为右上方、位于 1 号点方向为右方、位于 2 号点方向为右上方、位于 2 号点方向为右方。 对应代码顺序为 : 1, 0, 3, 2

    手推出从一个正六边形的四种状态走到下一个正六边形的四种状态所需要花费的最少体力,得到一个 4∗4 的转移矩阵 A,矩阵快速幂求出 (A^{k-x-1})

    ,其中矩阵乘法中的乘法运算和加法运算分别替换为加法运算和取min运算。于是 (A^{k-x-1})

    的元素分别表示从标号为 x 的正六边形的四种状态走到标号为 k-1 的正六边形的四种状态所需要花费的最少体力。

    之后手推出从标号为 x 的正六边形的 y 号点出发得到四种状态所需花费的最少体力,以及从标号为 k-1 的正六边形的四种状态出发得到标号为 k 的正六边形的 l 号点所需花费的最少体力。分别枚举四种状态更新答案即可。

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=(b);++i)
    #define per(i,a,b) for(int i=a;i>=(b);--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
    
    const int N = 100005;
    
    struct matrix
    {
        ll a[4][4];
    
        matrix() 
        { 
            rep (i, 0, 3) 
                rep (j, 0, 3)
                    a[i][j] = 2e18;
        }
    
        matrix operator * (matrix &B)
        {
            matrix C;
            rep (i, 0, 3)
                rep (j, 0, 3)
                    rep (k, 0, 3)
                        C.a[i][j] = min(C.a[i][j], a[i][k] + B.a[k][j]);
            return C;
        }
    
        matrix operator ^ (ll k)
        {
            matrix res, A = (*this);
            rep (i, 0, 4) res.a[i][i] = 0;
    
            for (; k; k >>= 1, A = A * A) 
                if(k & 1) res = res * A;
    
            return res;
        }
    }A;
    
    int n, m, _;
    ll a, b;
    
    ll trans[4][4] = 
    {
        {2,1,2,1},
        {1,2,1,0},
        {0,1,2,1},
        {1,2,1,2}
    };
    
    ll S[6][4] = 
    {
        {0,0,1,1},
        {1,1,0,0},
        {1,1,0,1},
        {0,1,1,1},
        {1,1,1,0},
        {1,0,1,1}
    };
    
    ll T[4][6] = 
    {
        {1,1,1,1,0,0},
        {1,0,1,1,0,1},
        {0,1,1,0,1,1},
        {1,1,0,0,1,1}
    };
    
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
    
        memcpy(A.a,trans, sizeof(trans));
    
        for (cin >> _; _; --_)
        {
            cin >> a >> n >> b >> m;
            if (a > b) swap(a, b), swap(n, m);
    
            if(a == b)
            {
                int x = (n - m + 6) % 6;
                if(x == 2 || x == 4) cout << 1 << '
    ';
                else cout << 0 << '
    ';
            }
            else if(a + 1 == b && (n == 1 || n == 2) && (m == 4 || m == 5)) cout << 0 << '
    ';
            else
            {
                matrix B = A ^ (b - a - 1);
                ll ans = 2e18;
                rep (i, 0, 3) 
                    rep (j, 0, 3)
                        ans = min(ans, S[n - 1][i] + B.a[i][j] + T[j][m - 1]);
                
                cout << ans << '
    ';
            }
        }
        return 0;
    }
    
  • 相关阅读:
    网络基础
    模块和包的介绍与使用
    PHP 接口输出 图片
    Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the
    dedeCMS 两个站共用同一个数据库 图片路径统一
    写入文件_调试方法
    Mysql触发器 使用示例
    部署GitLab遇到的问题记录
    防火墙对nginx服务器有影响
    更新yum源并重建缓存
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13134486.html
Copyright © 2011-2022 走看看