牛客编程巅峰赛S1第7场 - 黄金&钻石 A.dfs B.dpC.快速幂

链接:https://ac.nowcoder.com/acm/contest/6631/A
来源:牛客网

题目描述
题意
身为屯里第一剑士的牛牛来到训练场里闯关,由于过于勤奋,牛牛的宝剑的耐久度降到了 22 ,这意味着牛牛最多只能打倒两只怪兽,否则将会被淘汰。

训练场的地图可以看作一棵以 11 为根节点的树,训练场的终点为这棵树的叶子结点,树上的每个结点最多有一只怪兽,结点与结点间的边上没有怪兽。

每一个有怪兽的结点上牛牛都需要打倒怪兽才算安全,并且牛牛一旦选定好打怪路线之后便不能走回头路。

请问牛牛有多少种到达终点且不被淘汰的路径。

输入
第一个参数为 nn ,(1\leq n\leq 100,000)(1≤n≤100,000)

第二个参数为大小为 n-1n−1 的点对 (u_i, v_i)(u
i

,v
i

) 的集合,其中 (u_i, v_i)(u
i

,v
i

) 表示结点 u_iu
i

与结点 v_iv
i

之间有一条边,1\leq u_i, v_i \leq n1≤u
i

,v
i

≤n

第三个参数为大小为 nn 的 0/10/1 序列 ff ,若 f_if
i

为 00 表示i-1结点没有怪兽,否则表示 i-1 结点有怪兽。

返回
一个整数,表示牛牛能到达终点且不被淘汰的路径数。

示例1
输入
复制
7,[(7,2),(6,1),(5,2),(1,2),(4,6),(6,3)],[0,0,1,0,1,0,0]
输出
复制
4
说明
样例中的四条路径分别为: (1 - 2 - 7), (1 - 2 - 5) , (1 - 6 - 3), (1 - 6 - 4)

const int maxn=1e5+100;
vector<int>adj[maxn];
int cnt;
class Solution {
public:
    /**
     * 返回牛牛能到达终点且不被淘汰的路径数
     * @param n int整型
     * @param Edge Point类vector
     * @param f int整型vector
     * @return int整型
     */
    void dfs(int u, int fa, vector<int>& f, int num) {
         int son=0;
        for(auto i:adj[u]){
            if(i==fa)continue;
            son++;
            dfs(i,u,f,num+f[i-1]);            
        }
        if(son==0&&num<=2)cnt++;
        
    }
    int solve(int n, vector<Point>& Edge, vector<int>& f) {
        // write code here
        for(auto i:Edge){
            adj[i.x].push_back(i.y);
            adj[i.y].push_back(i.x);
        }
        dfs(1,-1,f,f[0]);
        return cnt;
    }
    
};

链接:https://ac.nowcoder.com/acm/contest/6631/B
来源:牛客网

题目描述
牛牛公司老板让牛牛负责m个冰激凌的运输。运输车的冷库只够装n个冰激凌,一次运输需要t分钟,返回也需要t分钟。每个冰激凌制作好有一个时间。牛牛想知道最短运输完所有冰激凌的时间,以及在时间最短的情况下最少运输次数。
示例1
输入
复制
2,3,10,[10,30,40]
输出
复制
[50,2]
备注:
(1≤n,m,t≤2000)

class Solution {
public:
    /**
     * 两个数表示答案
     * @param n int整型 一次运输的冰激凌数量
     * @param m int整型 总冰激凌数
     * @param t int整型 一次运输的时间
     * @param c int整型一维数组 表示每个冰激凌制作好时间<1e4
     * @param cLen int c数组长度
     * @return int整型vector
     */
    vector<int> icecream(int n, int m, int t, int* c, int len) {
        // write code here
        sort(c,c+len);
       int dp[2500],g[2500];
        memset(dp,0x7f,sizeof(dp));
        memset(g,0x7f,sizeof(g));
        for(int i=0;i<n;i++){
            dp[i]=c[i]+t;
            g[i]=1;
        }
        for(int i=1;i<m;i++){
           for(int k=1;k<=n;k++){
               int j=max(0,i-k);
               int newt=max(dp[j]+t+t,c[i]+t);
               if(newt<=dp[i]){
                  if(newt==dp[i])g[i]=min(g[i],g[j]+1);
                   else g[i]=g[j]+1;
                   dp[i]=newt;
               }
           }
             
        }
        vector<int>ans;
        ans.push_back(dp[m-1]);
        ans.push_back(g[m-1]);
        return ans;
         
    }
};

链接:https://ac.nowcoder.com/acm/contest/6631/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
已知a_0=0,a_1=1,a_i=b a_{i-1}+ c a_{i-2}(i\ge2)a
0

=0,a
1

=1,a
i

=ba
i−1

+ca
i−2

(i≥2),现在给你b和c两个系数的值,请你求出a_na
n

除以10^9+710
9
+7的余数。
(2 \leq n \leq 10^{18}, 0 \leq b,c \leq 10^9)(2≤n≤10
18
,0≤b,c≤10
9
)
示例1
输入
复制
2,1,1
输出
复制
1
示例2
输入
复制
5,1,2
输出
复制
11

const int mod=1e9+7;
typedef long long ll;
class Solution {
public:
    /**
     * 输出序列的第n项
     * @param n long长整型 序列的项数
     * @param b long长整型 系数
     * @param c long长整型 系数
     * @return long长整型
     */
    struct mat{
        ll a[2][2];
        friend mat operator*(mat a,mat b){
            mat ans;
            memset(ans.a,0,sizeof(ans.a));
            for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                    for(int k=0;k<2;k++){
                        ans.a[i][j]+=a.a[i][k]*b.a[k][j];
                        ans.a[i][j]%=mod;
                    }
                }
            }
            return ans;
        }
       
    };
    ll matpow(ll n,ll b,ll c){
        mat res;
        mat af;
        af.a[0][0]=b;
        af.a[0][1]=c;
        af.a[1][0]=1;
        af.a[1][1]=0;
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                if(i==j)res.a[i][j]=1;
                else res.a[i][j]=0;
            }
        }
        while(n){
            if(n&1)res=res*af;
            af=af*af;
            n>>=1;
        }
        return res.a[1][0];
    }
    long long nthElement(long long n, long long b, long long c) {
        // write code here
        return matpow(n,b,c);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值