c++算法篇

双指针算法

283.移动零

 

二分查找

1.朴素的二分查找

2.查找左边界和右边界的二分查找

二分法模板  

前缀和算法

快速求出数组中摸一个连续区间的和

DP34 【模板】前缀和

第一步:预处理出一个前缀和数组

例如:给定的数组arr[N],而前缀和数组dp[N],dp[i]=dp[i-1]+arr[i]

第二步:使用前缀和数组

一维数组求[l,r]之间的数之和,用dp[r]-dp[l-1]

数组下标从1开始(为了处理边界情况)

初始化:添加虚拟结点(辅助节点)

 

#include <iostream>
using namespace std;
#include<vector>
int main() {
    int n,q;
    cin>>n>>q;
    vector<int> arr(n+1);
    for(int i=1;i<=n;i++) cin>>arr[i];

    vector<long long> dp(n+1);
    for(int i=1;i<=n;i++) dp[i]=dp[i-1]+arr[i];

    while(q--)
    {
        int l,r;
        cin>>l>>r;
        cout<<dp[r]-dp[l-1]<<endl;
    }
}
// 64 位输出请用 printf("%lld")

DP35 【模板】二维前缀和

#include <iostream>
using namespace std;
#include<vector>

int main() {
    int n, m, q;
    cin >> n >> m >> q;
    const int N = 1010;
    int arr[N][N];
    long long vv[N][N];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> arr[i][j];
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            vv[i][j] = vv[i - 1][j] + vv[i][j - 1] + arr[i][j] - vv[i - 1][j - 1];
        }
    }
    for (int i = 1; i <= q; i++) {

        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        cout << vv[x2][y2] - vv[x1 - 1][y2] - vv[x2][y1 - 1] + vv[x1 - 1][y1 - 1] <<
             endl;

    }
}
// 64 位输出请用 printf("%lld")

 二维数组的初始化

vector<vector<int>> arr(n+1,vector<int>(m+1));

vector<vector<long long>>dp(n+1,vector<long long>(m+1));

位运算

1.基础运算

&:有0就是0

|:有1就是1

^:相同为0,相异为1/无进位相加

2.给一个数n,确定它的二进制表示中的第x位是0还是1

   n:0110101001   先让第x位右移(n>>x)&1

3.将一个数n的二进制表示的第x位修改成1

        0110101011

|       0000001000(1<<x)

        0110101011

 n | =(1<<x)

4.将一个数n的二进制表示的第x位修改成0

       0110101100

&     1111011111

       0110001100

n&=(~(1<<x))

5.位图的思想

6.提取一个数(n)二进制表示最右侧的1

     01110101000

     00000001000

n & -n  将最右侧的1,左边的区域全部变成相反

       0110101000

~    1001010111

+1  1001011000

&    0110101000

      0000001000

7.干掉一个数(n)二进制表示中最右侧的1

     n &(n-1)

n        011010100

n-1     011010011      让最右侧的1右边区域(包含1)全部变成相反

&        011010000

题号:191 338 461(leetcode轻松解决)

8.位运算的优先级

能加括号就加括号

9.异或(^)运算的运算律 

a^0=a

a^a=0

a^b^c=a^(b^c)     

          1011010

          0010101

^        1010001

          0011110

解决:(leetcode 136 260)

进位问题

371. 两整数之和

class Solution {
public:
    int getSum(int a, int b) {
        while (b != 0) {
            int x = a ^ b; // 先算出⽆进位相加的结果
            unsigned int carry = (unsigned int)(a & b) << 1; // 算出进位
            // 排除-1左移一直为1
            a = x;
            b = carry;
        }
        return a;
    }
};

模拟

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值