<!-- wp:heading {"level":1} -->
<h1>牛客编程巅峰赛S2第3场</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>-> 青铜&白银&黄金
https://ac.nowcoder.com/acm/contest/9246
钻石&王者
https://ac.nowcoder.com/acm/contest/9247
2020-11-24 20:00:00 至 2020-11-24 21:00:00
时长: 1小时
AC 2/3
Rank 195/696
罚时 01:44:59
A (555/1916) 00:20:15 (-1)
B (205/1349) 00:59:44 (-4)
C (56/187)</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>A 牛牛打怪</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>牛牛在各个平台被各种传奇游戏的广告轰炸,所以他决定去玩一玩这类的游戏。这类游戏挂机就可以升级,所以牛牛每天都能变强。在第i天里,牛牛能杀死防御力小于等于i的怪物。但由于牛牛还要刷题,所以牛牛每天最多杀一只怪物。这个游戏共有n只怪物,每只怪物的防御力为DEF[i],牛牛想知道最少要到第几天才能把这n只怪物都杀死。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>A.1 比赛时AC</h3>
<!-- /wp:heading -->

<!-- wp:code -->

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 
     * @param DEF int整型vector 
     * @return int整型
     */
    int Minimumdays(int n, vector<int>& DEF) {
        // write code here
        sort(DEF.begin(),DEF.end());
        for(int i=1;i<n;i++){
            if(DEF[i]<=DEF[i-1]){
                DEF[i]=DEF[i-1]+1;
            }
        }
        return max(n,DEF[n-1]);
    }
};

<!-- /wp:code -->

<!-- wp:paragraph -->
<p>思路这样解释比较形象:
从小到大排列后,如果有相同数值的会形成一个平台。
而一天内最多只能打一个,
所以平台内的第二天需要增高一个台阶,
后面类似,小于等于前一个的数值将被更改为前一个的数值加一。
if(DEF[i]<=DEF[i-1]) DEF[i]=DEF[i-1]+1;</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>A.2 讲解</h3>
<!-- /wp:heading -->

<!-- wp:code -->

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 
     * @param DEF int整型vector 
     * @return int整型
     */
    int Minimumdays(int n, vector<int>& DEF) {
        // write code here
        sort(DEF.begin(),DEF.end());
        int cnt=DEF[0],i;
        for(i=1;i<DEF.size();i++){
            cnt=max(DEF[i],cnt+1);
        }
        return cnt;
    }
};

<!-- /wp:code -->

<!-- wp:heading -->
<h2>B 简单的公式</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>现在有3个数组a,b,c
a[1]=2,a[2]=6,对所有的n>=3,$latex a[n] = 2<em>a[n-1] + 3</em>a[n-2]$。
b[1]=7,b[2]=35,对所有的n>=3,$latex b[n] = 3<em>b[n-1] + 10</em>b[n-2]$。
对所有的n>=1,有c[n] = a[n]*b[n]。
现在给你一个正整数n,返回c[n]%1000000007的值。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>B.1 比赛时AC</h3>
<!-- /wp:heading -->

<!-- wp:code -->

class Solution {
public:
    /**
     * 返回c[n]%1000000007的值
     * @param n long长整型 即题目中的n
     * @return int整型
     */
    int Answerforcn(long long n) {
        // write code here
        long long a=15,b=n-1,c=1000000007;
        long long ans = 14,base=a;
        base = base % c;

        if(b==0){
        return 14%c;
        } 
        while(b){   
            if(b & 1)
            ans = (ans*base) % c; 
            b = b >> 1;
            base = (base * base) % c; 
         } 
        return ans%c;
    }
};

<!-- /wp:code -->

<!-- wp:paragraph -->
<p>其实这道题算作弊了。。
一开始没想到怎么算通项公式,
直接用特征方程来解的。</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->

<p>$latex x_n=p\cdot x_{n-1}+q\cdot x_{n-2}\rightarrow x^2-px-q=0$
解得 $latex x=a,b$
通项公式为$latex x_n=\alpha\cdot a^{n-1}+\beta\cdot b^{n-1}$
其中$latex \alpha,\beta$由初始条件$latex x_1,x_2$求得。
$latex \alpha=\frac{x_2-bx_1}{a-b},\beta=\frac{x_2-ax_1}{b-a}$</p>
<!-- /wp:quote --> <!-- wp:paragraph --> <p>后面算出$latex c_n=14\cdot 15^{n-1}$之后超时了一次。
然后莫名其妙觉得余数会循环(并不会循环)。浪费了很多时间
搜了下“幂取模”,搜到了模板 | 整数快速幂 & 快速幂取模,。</p> <!-- /wp:paragraph --> <!-- wp:code -->
// time:O(logN)
// 这里不考虑指数为负数的情况
int pow_mod(int a,int b,int  c)  
{
    int ans = 1,base=a;// ans:结果;base:底数
    base = base % c;
    //【考虑0次方的情况】
    if(b==0)
    {
        return 1%c;// 任意a的0次幂都是1,故直接用1%c即可 
    } 
    while(b)
    {   
        if(b & 1) // 与运算,判断奇偶性
        ans = (ans*base) % c; 
        b = b >> 1;// 右移一位,相当于除2
        base = (base * base) % c; 
    } 
    return ans;
} 

<!-- /wp:code -->

<!-- wp:paragraph -->
<p>就直接套进来了,一开始还忘记改b=0的情况了,后来改成14,终于AC了,2020-11-24 20:59:44,还差16秒结束,终于赶上了一道。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>B.2 讲解</h3>
<!-- /wp:heading -->

<!-- wp:code -->

class Solution {
public:
    /**
     * 返回c[n]%1000000007的值
     * @param n long长整型 即题目中的n
     * @return int整型
     */
    typedef long long ll;
    int mod=1e9+7;
    ll power(ll a,ll b){
        ll res=1;
        while(b){
            if(b%2==1)res=res*a%mod;
            b/=2;
            a=a*a%mod;
        }
        return res;
    }
    int Answerforcn(long long n) {
        // write code here
        return 14*power(15,n-1)%mod;
    }
};

<!-- /wp:code -->

<!-- wp:heading -->
<h2>C Tree VI</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>系统中有一棵n个点的完全k叉树,现给出它的DFS先序遍历序列$latex a_i$ ,请你还原这棵树,并返回加密后的答案。
答案加密方法:所有边两个端点异或的和,即$latex \sum\limits_{i=1}^{n-1}u_i\ xor\ v_i$ ,其中$latex (u_i, v_i)$为一条树上的边。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>下面给出完全二叉树的定义:若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k层所有的结点都连续集中在最左边。
请你根据这个定义进行适度推广,得到完全k叉树的含义。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>C.1 比赛时</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>又没做到这一题,太惨了。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>C.2 讲解</h3>
<!-- /wp:heading -->

<!-- wp:code -->

class Solution {
public:
    /**
     * 
     * @param k int整型 表示完全k叉树的叉数k
     * @param a int整型vector 表示这棵完全k叉树的Dfs遍历序列的结点编号
     * @return long长整型
     */
    typedef long long ll;
    ll kk,nn,temp=1,res=0;
    vector<int> aa;
    void dfs(int x,int cnt){
        int i;
        for(i=1;i<=kk;i++){
            if(kk*x+i<nn){
                temp++;
                res+=aa[temp-1]^aa[cnt-1];
                dfs(kk*x+i,temp);
            }
            else return;
        }
    }
    long long tree6(int k, vector<int>& a) {
        // write code here
        kk=k ,nn=a.size(),aa=a;
        dfs(0,1);
        return res;
    }
};

<!-- /wp:code -->

<!-- wp:paragraph -->
<p>引入BFS 辅助思考</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>D 整除问题</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>给定 $latex a, b, c, d$,求所有 $latex x\times y$ 被 2021 整除的 $latex (x, y)$ 数对个数,其中 $latex a\le x\le b, c\le y\le d$ 。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>D.1 讲解</h3>
<!-- /wp:heading -->

<!-- wp:code -->

class Solution {
public:
    /**
     * 寻找所有能整除 2021 的数对个数
     * @param a long长整型 
     * @param b long长整型 
     * @param c long长整型 
     * @param d long长整型 
     * @return long长整型
     */
    long long f(long long a, long long b){
        return a/2021b+b/2021a-a/2021(b/2021)+(a/43-a/2021)(b/47-b/2021)+(a/47-a/2021)*(b/43-b/2021);
    }
    long long findPairs(long long a, long long b, long long c, long long d) {
        // write code here
        return f(b,d)-f(a-1,d)-f(b,c-1)+f(a-1,c-1);
    }
};

<!-- /wp:code -->

<!-- wp:paragraph -->
<p>容斥原理</p>
<!-- /wp:paragraph -->

最后修改:2020 年 12 月 22 日 07 : 03 PM
如果觉得我的文章对你有用,请随意赞赏