可达鸭二月月赛——基础赛第六场(周五)题解,这次四个题的题解都在这一篇文章内,满满干货,含有位运算的详细用法介绍。

姓名

  • 王胤皓

T1 题解

T1 题面

可达鸭二月月赛——基础赛第六场(周五)题解,这次四个题的题解都在这一篇文章内,满满干货,含有位运算的详细用法介绍。_第1张图片

T1 思路

样例输入就是骗人的,其实直接输出就可以了,输出 Hello 2024,注意,中间有一个空格!

T1 代码

#include
using namespace std;
#define ll long long
int main(){
	cout<<"Hello 2024";
	return 0;
}

T2 题解

T2题面

可达鸭二月月赛——基础赛第六场(周五)题解,这次四个题的题解都在这一篇文章内,满满干货,含有位运算的详细用法介绍。_第2张图片

T2 思路

计算 2 x 2^x 2x 次方,可以使用 C++ 中自带的位运算。

接下来将详细介绍位运算:
位运算是计算机中一种常用的运算方式,它直接对二进制数据进行操作。C++语言提供了多种位运算操作符与函数,可以方便地进行位运算。

一、位运算的基础概念

  1. 二进制表示:在计算机中,所有的数据都是以二进制形式表示的。一个二进制位可以表示0或1,多个二进制位可以表示更大的数值。
  2. 位运算操作符:C++提供了多种位运算操作符,包括与(&)、或(|)、异或(^)、取反(~)等。
  3. 位运算函数:C++提供了一些位运算函数,包括位移函数(<<、>>)、位计数函数(__builtin_popcount)、最低位函数(__builtin_ffs)等。

二、位运算操作符

  1. 与运算(&):对两个数的二进制位进行逐位比较,若两个位均为1,则结果为1;否则为0。例如,3 & 5的结果是1。
  2. 或运算(|):对两个数的二进制位进行逐位比较,若两个位中至少有一个为1,则结果为1;否则为0。例如,3 | 5的结果是7。
  3. 异或运算(^):对两个数的二进制位进行逐位比较,若两个位不相同,则结果为1;否则为0。例如,3 ^ 5的结果是6。
  4. 取反运算():对一个数的二进制位进行逐位取反,即0变为1,1变为0。例如,3的结果是-4(以补码形式表示)。
  5. 左移运算(<<):将一个数的二进制位向左移动指定的位数,相当于乘以2的指定次幂。例如,3 << 2的结果是12。
  6. 右移运算(>>):将一个数的二进制位向右移动指定的位数,相当于除以2的指定次幂。例如,8 >> 2的结果是2。

三、位运算的应用

  1. 位运算与(&)常用于掩码操作、判断奇偶性等。例如,可以用掩码操作实现只保留某些位。
  2. 位运算或(|)常用于设置某些位为1。例如,可以用位运算将某些位设置为1,而保持其他位不变。
  3. 位运算异或(^)常用于交换两个数的值、判断两个数的符号是否相同等。
  4. 位运算取反(~)常用于将整数取反。
  5. 位运算左移(<<)和右移(>>)常用于对整数进行乘法或除法的优化。例如,一个数左移一位相当于乘以2,右移一位相当于除以2。

四、位运算的特点

  1. 位运算是直接对二进制数据进行操作,因此速度较快。
  2. 位运算在一些特定场景下可以实现高效的算法,如位图算法、哈希表实现等。
  3. 位运算可以用于优化算法性能,减少空间占用。

五、注意事项

  1. 在使用位运算时,需要注意位运算的优先级与结合性,可以使用括号来明确运算顺序。

总结:位运算是C++中一种常用的运算方式,可用于对二进制数据进行操作。C++提供了多种位运算操作符和函数,方便进行位运算。位运算具有速度快、可以实现高效算法、可以优化性能的特点。在使用位运算时,需要注意操作符优先级和结合性。

所以直接输出 2 n 2^n 2n 也就是 1 < < n 1<1<<n

(我绝不会告诉你有人还用快速幂、pow和for循环)

T2 代码

#include
using namespace std;
#define ll long long
int main(){
    int n;
    cin>>n;
	cout<<(1<<n);
	return 0;
}

T3 题解

T3 题面

可达鸭二月月赛——基础赛第六场(周五)题解,这次四个题的题解都在这一篇文章内,满满干货,含有位运算的详细用法介绍。_第3张图片

T3 O ( n ) O(n) O(n) 思路

暴力枚举。

遍历 l l l r r r,然后如果 i i i 为奇数,那么计数器加上 i i i,最后进行输出即可。

T3 O ( n ) O(n) O(n) 代码

#include
using namespace std;
#define ll long long
int main(){
    int l,r;
    cin>>l>>r;
    int sum=0;
    for(int i=l;i<=r; i++){
        if(i&1) sum+=i;
    }
    cout<<sum;
	return 0;
}

T3 O(1) 思路

前置知识(干货):因为 1 + 3 + 5 + 7 + 9 = ⌊ 9 + 1 2 ⌋ 2 1+3+5+7+9=\lfloor \frac{9+1}{2}\rfloor^2 1+3+5+7+9=29+12,从而得出 1 + 3 + 5 + ⋯ + n ( n m o d    2 = 1 ) = ⌊ n + 1 2 ⌋ 2 1+3+5+\cdots+n(n\mod 2=1)=\lfloor \frac{n+1}{2}\rfloor^2 1+3+5++n(nmod2=1)=2n+12

接下来进行分类讨论:

  • 如果 l l l r r r 都是奇数,那么根据约分性质 ( a + b + c + d ) − ( a + b ) = c + d (a+b+c+d)-(a+b)=c+d (a+b+c+d)(a+b)=c+d,就能得出 1 + 3 + 5 + ⋯ + r 1+3+5+\cdots +r 1+3+5++r 1 + 3 + 5 + ⋯ + ( l − 2 ) 1+3+5+\cdots +(l-2) 1+3+5++(l2),得出答案是 1 + 3 + 5 + ⋯ + r − ( 1 + 3 + 5 + ⋯ + ( l − 2 ) ) 1+3+5+\cdots +r-(1+3+5+\cdots +(l-2)) 1+3+5++r(1+3+5++(l2)),简化后为 r + 1 2 2 − l − 2 + 1 2 2 \frac{r+1}{2}^2-\frac{l-2+1}{2}^2 2r+122l2+12
    Q:为什么 l l l 要减 2 2 2?
    A:如果不减的话,那么就会少算一个 l l l
  • 如果 l l l 是奇数, r r r 是偶数,那么要把 r r r 1 1 1,然后就可以和 l l l r r r 都是奇数的计算就是一样的了,就能得出 1 + 3 + 5 + ⋯ + r 1+3+5+\cdots +r 1+3+5++r 1 + 3 + 5 + ⋯ + ( l − 2 ) 1+3+5+\cdots +(l-2) 1+3+5++(l2),得出答案是 1 + 3 + 5 + ⋯ + r − ( 1 + 3 + 5 + ⋯ + ( l − 2 ) ) 1+3+5+\cdots +r-(1+3+5+\cdots +(l-2)) 1+3+5++r(1+3+5++(l2)),简化后为 r + 1 2 2 − l − 2 + 1 2 2 \frac{r+1}{2}^2-\frac{l-2+1}{2}^2 2r+122l2+12
    Q:为什么 l l l 要减 2 2 2?
    A:如果不减的话,那么就会少算一个 l l l
  • 如果 l l l 是偶数, r r r 都是奇数,把 l + 1 l+1 l+1 ,然后就可以和 l l l r r r 都是奇数的计算就是一样的了,那么根据约分性质 ( a + b + c + d ) − ( a + b ) = c + d (a+b+c+d)-(a+b)=c+d (a+b+c+d)(a+b)=c+d,就能得出 1 + 3 + 5 + ⋯ + r 1+3+5+\cdots +r 1+3+5++r 1 + 3 + 5 + ⋯ + ( l − 2 ) 1+3+5+\cdots +(l-2) 1+3+5++(l2),得出答案是 1 + 3 + 5 + ⋯ + r − ( 1 + 3 + 5 + ⋯ + ( l − 2 ) ) 1+3+5+\cdots +r-(1+3+5+\cdots +(l-2)) 1+3+5++r(1+3+5++(l2)),简化后为 r + 1 2 2 − l − 2 + 1 2 2 \frac{r+1}{2}^2-\frac{l-2+1}{2}^2 2r+122l2+12
    Q:为什么 l l l 要减 2 2 2?
    A:如果不减的话,那么就会少算一个 l l l
  • 如果 l l l r r r 都是偶数,那么结合第二项和第三项,在进行第一项的操作就可以了,就是 l + 1 , r − 1 l+1,r-1 l+1,r1,那么根据约分性质 ( a + b + c + d ) − ( a + b ) = c + d (a+b+c+d)-(a+b)=c+d (a+b+c+d)(a+b)=c+d,就能得出 1 + 3 + 5 + ⋯ + r 1+3+5+\cdots +r 1+3+5++r 1 + 3 + 5 + ⋯ + ( l − 2 ) 1+3+5+\cdots +(l-2) 1+3+5++(l2),得出答案是 1 + 3 + 5 + ⋯ + r − ( 1 + 3 + 5 + ⋯ + ( l − 2 ) ) 1+3+5+\cdots +r-(1+3+5+\cdots +(l-2)) 1+3+5++r(1+3+5++(l2)),简化后为 r + 1 2 2 − l − 2 + 1 2 2 \frac{r+1}{2}^2-\frac{l-2+1}{2}^2 2r+122l2+12
    Q:为什么 l l l 要减 2 2 2?
    A:如果不减的话,那么就会少算一个 l l l

T3 O(1) 代码

#include
using namespace std;
#define ll long long
int main(){
	int l,r;
	cin>>l>>r;
	if(r&1==0) r--;
	l--;
	if(l&1==0) l--;
	cout<<(((r+1)/2)*((r+1)/2)-((l+1)/2)*((l+1)/2))<<endl;
	return 0;
}

T4 题解

T4 题面

可达鸭二月月赛——基础赛第六场(周五)题解,这次四个题的题解都在这一篇文章内,满满干货,含有位运算的详细用法介绍。_第4张图片

T4 思路

遍历字符串,如果 s i s_i si s i + 1 s_{i+1} si+1 都是 l,那么计数器 + 1 +1 +1,然后把 i i i 也加 1 1 1,防止重复计算。

判断 s i = = ′ d ′ s_i=='d' si==d 并且 s i + 1 = = ′ r ′ s_{i+1}=='r' si+1==r 并且 s i + 2 = = ′ a ′ s_{i+2}=='a' si+2==a 并且 s i + 3 = = ′ g ′ s_{i+3}=='g' si+3==g 并且 s i + 4 = = ′ o ′ s_{i+4}=='o' si+4==o 并且 s i + 5 = = ′ n ′ s_{i+5}=='n' si+5==n,可以使用 string 中的 substr 函数简化,函数格式:字符串名字.substr(截取字符串开始下标,截取长度),直接判断是否为 d r a g o n dragon dragon 就可以了。那么计数器也 + 1 +1 +1,然后 i + 5 i+5 i+5,防止重复计算。

T4 代码

#include
using namespace std;
#define ll long long
int main(){
    int n;
    cin>>n;
    while(n--){
        string s;
        cin>>s;
        int cnt=0;
        for(int i=0; i<s.size()-1; i++){
            if(s[i]=='l'&&s[i+1]=='l'){
                i++;
                cnt+=2;
            }
            if(s.substr(i,6)=="dragon") cnt++,i+=5;
        }
        cout<<cnt<<endl;
    }
	return 0;
}

赛后总结

T1,T2,T3,T4真的都太水了,太简单了,前三题时间复杂度都可以做到 O ( 1 ) O(1) O(1),第四题最坏情况下是 O ( T × n ) O(T\times n) O(T×n)

贴图:
在这里插入图片描述
给个三连,你的三连是给我创作文章的最大的动力!

你可能感兴趣的:(C/C++,编程,题解,算法,c++,学习)