牛客2020年七夕节比赛BCE

一道有意思的题目

https://ac.nowcoder.com/acm/contest/7009/A

B题

  • 所以大于3的时候答案就是0了,那么小于三的时候,就需要特判了,而等于三的时候就需要自己一个一个算就好了
#include <iostream>
#include <sstream>
using namespace std;

int main()
{

    long long n,m;
    int t;
    cin >> t;
    while(t --)
    {
        cin >> n >> m;
        if(n > 3){
            cout << 0 << endl;
        }
        else if(n == 3){
            long long res = 1;
            for(long long i = 1;i <= 720;i ++)
            {
                res *= i;
                res %= m;
            }
            cout << res << endl;
        }
        else if(n == 1 || n == 2){
            cout << n % m << endl;
        }
        else if(n == 0){
            cout << 1 % m << endl;
        }
    }

    return 0;
}

C题

  • 这个题照着图画就好了
#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    cout << "I love U forever." << endl;
    int base = n;
    int kong = n,kong2 = n * 2 - 1;
    for(int i = 0;i < n;i ++)
    {
        for(int j = 0;j < kong;j ++)
            cout << ' ';

        for(int j = 0;j < base;j ++)
            cout << '*';

        for(int j = 0;j < kong2;j ++)
            cout << ' ';
        for(int j = 0;j < base;j ++)
            cout << '*';
        base += 2;
        kong -= 1;
        kong2 -= 2;
        cout << endl;
    }

    for(int i = 0;i < n * 3;i ++)
    {
        for(int j = 0;j < kong;j ++)
            cout << ' ';
        for(int j = 0;j < base;j ++)
            cout << '*';
        for(int j = 0;j < base - 1;j ++)
            cout << '*';
        base -= 1;
        kong += 1;
        cout << endl;
    }


    return 0;
}

/*

I love U forever.
 * * 1 1
*****
 ***
  *
I love U forever.
   ***     *** 3 5
  *****   *****2 3
 ******* *******1 1
*****************
 ***************
  *************
   ***********
    *********
     *******
      *****
       ***
        *
I love U forever.
  **   ** 2 3
 **** ****1 1
***********
 *********
  *******
   *****
    ***
     *
*/

E题

  • 按照题目给的公式来求取最终答案,首先我们先要算出有多少次是不挨揍的,假设c到b的距离+b到1号的距离之和为dis
  • 设a到1号点的距离为dep
  • if(max(dep,dis) < t),那么牛牛就算成功
  • a到1号点的距离很好求,bfs或者dfs算出距离来,depth数组是记录每个点到0号点的距离
  • 那么c->b->1这个怎么求呢
  • 我大体分为了三种情况(可能这里有重复的情况,当时没考虑太多)
  • 假设b和c的最近公共祖先为f点
    1. f == b ,2. f == c, 3. f != c && f != b
  • 对于第一种情况那么dis就是 c -> b -> 1 ,dis也就是 depth[c] - 1(这里我设置的根节点为0号点,depth[1] = 1,depth[0] = 0)
  • 对于第二种情况那么我们就需要这样走,c -> b,然后再从b -> c,然后再从c到1号点,那么dis就是 (depth[b] - depth[c]) * 2 + depth[c] - 1;
  • 对于第三种情况 首先是 c -> f,然后f -> b,然后b -> 1,dis = (depth[c] - depth[f]) + (depth[b] - depth[f]) + (depth[b] - 1);
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>

using namespace std;

typedef long long LL;
const long long mod = 1e9 + 7;
const long long N = 1e6 + 10;
long long fa[N][16];
long long n,m;
long long depth[N];
vector<long long>v[N];

LL qpow(LL a,LL k)
{
    LL res = 1;
    while(k)
    {
        if(k & 1)
            res = (long long)res * a % mod;
        a = (long long )a * a % mod;
        k >>= 1;
    }
    return res;
}

LL inv(LL x)
{
    return qpow(x,mod - 2) % mod;
}


void bfs(long long root)
{
    memset(depth,0x3f,sizeof depth);

    depth[root] = 1;
    depth[0] = 0;
    queue<long long>q;
    q.push(root);

    while(q.size())
    {
        long long t = q.front();q.pop();

        for(auto &x : v[t])
        {
            if(depth[x] > depth[t] + 1)
            {
                depth[x] = depth[t] + 1;
                q.push(x);
                fa[x][0] = t;

                for(long long i = 1;i <= 15;i ++)
                {
                    fa[x][i] = fa[fa[x][i - 1]][i - 1];
                }
            }
        }
    }
}

long long lca(long long a,long long b)
{
    if(depth[a] < depth[b]) swap(a,b);

    for(long long i = 15;i >= 0;i --)
    {
        if(depth[fa[a][i]] >= depth[b])
        {
            a = fa[a][i];
        }
    }
    if(a == b) return a;
    for(long long i = 15;i >= 0;i --)
    {
        if(fa[a][i] != fa[b][i])
        {
            a = fa[a][i];
            b = fa[b][i];
        }
    }
    return fa[a][0];
}


int main()
{
    cin >> n;
    long long root = 1;
    for(long long i = 0;i < n - 1;i ++)
    {
        long long a,b;
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }

    bfs(root);
    cin >> m;
    long long q = m;
    long long a,b,c,t;

    long long sum = 0;

   /* for(int i = 1;i <= n;i ++)
    {
        cout << "```" << depth[i] << endl;
    }*/

    while(m --)
    {
        cin >> a >> b >> c >> t;

        long long dep = depth[a] - 1;

        long long f = lca(b,c);
        long long dis;
        // cout << f << endl ;
        if(f == b){
            dis = depth[c] - 1;
        }
        else if(f == c){
            dis = (depth[b] - depth[c]) * 2 + depth[c] - 1;
        }
        else{
            dis = depth[c] - depth[f] + depth[b] - depth[f] + depth[b] - 1;
        }

        dep = max(dis,dep);
        if(dep < t){
            sum ++;
        }
        // cout << dep <<' ' <<  dis << endl;
    }


    LL ans = sum * inv(q) % mod;

    cout << ans << endl;

    return 0;
}

如果有哪里写的不对,还请大佬指正。。。。。

全部评论
那个求inv的过程可以参照C题的上半部分,这里我解释了一下:https://blog.nowcoder.net/n/7dd5122b29694d46a42adc33f37b779e
点赞 回复 分享
发布于 2020-08-26 08:59

相关推荐

专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务