牛客编程巅峰赛S1第7场 - 黄金&钻石A-B-C

比赛链接:牛客编程巅峰赛S1第7场 - 黄金&钻石

A.牛牛打怪兽 DFS

题意
身为屯里第一剑士的牛牛来到训练场里闯关,由于过于勤奋,牛牛的宝剑的耐久度降到了 2 ,这意味着牛牛最多只能打倒两只怪兽,否则将会被淘汰。
训练场的地图可以看作一棵以1为根节点的树,训练场的终点为这棵树的叶子结点,树上的每个结点最多有一只怪兽,结点与结点间的边上没有怪兽。
每一个有怪兽的结点上牛牛都需要打倒怪兽才算安全,并且牛牛一旦选定好打怪路线之后便不能走回头路。
请问牛牛有多少种到达终点且不被淘汰的路径。
输入
第一个参数为 n ,(1≤n≤100,000)
第二个参数为大小为 n-1 的点对 ( u i u_i ui, v i v_i vi)的集合,其中 ( u i u_i ui, v i v_i vi)表示结点 u i u_i ui 与结点 v i v_i vi之间有一条边,1≤ u i u_i ui , v i v_i vi ≤n,第三个参数为大小为 n 的 0/1 序列 f ,若 f i f_i fi为 0 表示i-1结点没有怪兽,否则表示 i-1 结点有怪兽。
返回
一个整数,表示牛牛能到达终点且不被淘汰的路径数。

class Solution {
public:
vector<vector<int> >v;
vector<int>vis,val;
int ans;
bool check(int id)
{
    for(int i=0;i<v[id].size();i++)
        if(vis[v[id][i]]==0)return 0;
    return 1;
}
void dfs(int id,int sum)
{
    if(sum>2)return;
    if(check(id))ans++;
    for(int i=0;i<v[id].size();i++){
        if(vis[v[id][i]]==0){
            vis[v[id][i]]=1;
            dfs(v[id][i],sum+val[v[id][i]]);
        }
        
    }
}
int solve(int n, vector<Point>& edge, vector<int>& f)
{
    ans=0;
    v.resize(n+1);
    vis.resize(n+1);
    val.resize(n+1);
    for(auto it:edge){
        v[it.x].push_back(it.y);
        v[it.y].push_back(it.x);
    }
    for(int i=1;i<=n;i++){
        vis[i]=0;val[i]=f[i-1];
    }
    vis[1]=1;
    dfs(1,val[1]);
    return ans;
}
};

B.牛牛的冰激凌 贪心

牛牛公司老板让牛牛负责m个冰激凌的运输。运输车的冷库只够装n个冰激凌,一次运输需要t分钟,返回也需要t分钟。每个冰激凌制作好有一个时间。牛牛想知道最短运输完所有冰激凌的时间,以及在时间最短的情况下最少运输次数。

class Solution {
public:
vector<int> icecream(int n, int m, int t, int* c, int cLen)
{
    sort(c, c + m);
    int remain = m % n;
    if (!remain) remain = n;
    int ans =0;
    for (int i = remain - 1; i < m; i += n) {
        ans = max(ans, c[i]);
        ans += 2*t;
    }
    return {ans-t, m / n + (m % n != 0) };
}
};

C.数列求值 矩阵快速幂

已知 a 0 = 0 , a 1 = 1 a_0=0,a_1=1 a0=0,a1=1 a i = b a i − 1 + c a i − 2 a_i=b a_{i-1}+ c a_{i-2} ai=bai1+cai2
(i≥2),现在给你b和c两个系数的值,请你求出 a n a_n an
除以10^9+7的余数。
( 2 ≤ n ≤ 1 0 18 , 0 ≤ b , c ≤ 1 0 9 ) ( 2 ≤ n ≤ 1 0 18 , 0 ≤ b , c ≤ 109 ) (2 \leq n \leq 10^{18}, 0 \leq b,c \leq 10^9)(2\leq n \leq 10^{18},0\leq b,c \leq 10 9) (2n1018,0b,c109)(2n1018,0b,c109)

#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
const long long mod = 1e9+7;
class Solution {
public:
struct Matrix {
  long long a[3][3];
  Matrix() { memset(a, 0, sizeof a); }
  Matrix operator*(const Matrix &b) const {
    Matrix res;
    for (int i = 0; i < 2; ++i)
      for (int j = 0; j < 2; ++j)
        for (int k = 0; k < 2; ++k)
          res.a[i][j] = (res.a[i][j] + a[i][k] * b.a[k][j]) % mod;
    return res;
  }
} ans, base;

void init(long long x,long long y) {
  base.a[0][0] = x; 
  base.a[0][1] = 1;
  base.a[1][0] = y;
  ans.a[0][0] =x; ans.a[0][1] = 1;
}

void qpow(long long b) {
  while (b) {
    if (b & 1) ans = ans * base;
    base = base * base;
    b >>= 1;
  }
}
long long nthElement(long long n, long long x, long long y)
{
    
    if(n==0)return 0;
    if(n==1)return 1;
    init(x,y);
    qpow(n-2);
    return ans.a[0][0]%mod;
}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值