【acwing算法基础】java和C++ 第一章

学习路线:

第一章 基础算法

一、排序

1.快排

2.归并

 1.快速排序

题目:785.快速排序

c题解

java题解

import java.util.Scanner;

public class QuickSort {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = 1000000;
        int[] q = new int[N + 1];
        int n = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            q[i] = sc.nextInt();
        }
        quick_sort(q, 0, n - 1);
        for (int i = 1; i <= n; i++) {
            System.out.printf("%d ", q[i]);
        }
    }

    public static void quick_sort(int q[], int l, int r) {
        if (l >= r) return;

        int x = q[l], i = l - 1, j = r + 1;
        while (i < j) {
            do i++; while (q[i] < x);
            do j--; while (q[j] > x);
            if (i < j) {
                int t = q[i];
                q[i] = q[j];
                q[j] = t;
            }
        }
        quick_sort(q, l, j);
        quick_sort(q, j + 1, r);
    }
}

2.归并排序

题目:787.归并排序

c题解

java题解

import java.util.Scanner;

public class MergeSort {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int N = 1000010;
        int[] q = new int[N];
        for (int i = 0; i < n; i++) {
            q[i] = sc.nextInt();
        }

        marge_sort(q, 0, n - 1);

        for (int i = 0; i < n; i++) {
            System.out.printf("%d ", q[i]);
        }

    }

    public static void marge_sort(int[] q, int l, int r) {
        if (l >= r) return;

        int mid = l + r >> 1;
        int[] tmp = new int[1000010];
        marge_sort(q, 0, mid);
        marge_sort(q, mid + 1, r);

        int i = l;
        int j = mid + 1; // mid + 1
        int k = 0;// k和tmp用来存储已经排好序的数组
        while (i <= mid && j <= r) {
            if (q[i] <= q[j]) tmp[k++] = q[i++];
            else tmp[k++] = q[j++];
        }
        //比完后剩下的
        while (i <= mid) {
            tmp[k++] = q[i++];
        }
        while (j <= r) {
            tmp[k++] = q[j++];
        }
        //放回q数组中,i必须是l而不能是0,i小于等于r
        for (i = l, j = 0; i <= r; i++, j++) {
            q[i] = tmp[j];
        }
    }
}

二、二分

1.整数

2.实数

1.整数二分

有单调性一定可以二分,没有单调性也可能可以二分

更新区间l = mid 时要+1,r = mid 时不用+1

题目:789.数的范围

C语言

java题解

import java.util.Scanner;

public class ErFenZhengShu {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] q = new int[n];
        for (int i = 0; i < n; i++) {
            q[i] = sc.nextInt();
        }
        // 询问个数
        while(m-- > 0) {
            int x = sc.nextInt();

            int l = 0;
            int r = n - 1;
            while (l < r) {
                int mid = l + r >> 1;//要不要加一后面再说
                if (q[mid] >= x) { //在右半边mid = l+r/2
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            //循环结束后r = l
            if (q[l] != x) { //此时l就是第一个x的位置了(左边界)
                System.out.println("-1 -1");
            } else {
                System.out.printf("%d ",l);

                l = 0;
                r = n - 1;
                while (l < r) {
                    int mid = l + r + 1 >> 1;
                    if (q[mid] <= x) l = mid; //再看右边界
                    else r = mid - 1;
                }
                System.out.printf("%d", l);
            }
        }
    }
}

2.浮点数二分

C语言

java

import java.util.Scanner;

public class ErFenFuDian {
    public static void main(String[] args) {
        // 求根号x
        Scanner sc = new Scanner(System.in);
        double x = sc.nextDouble();
        double l = 0;
        double r = x; //根号一定在0-x区间内
        while (r - 1 > 1e-4) { //10的-6次方可以近似看作答案了  比要求的有效位数多2
            double mid = (l + r) / 2; //不能用>>1
            if (mid * mid >= x) r = mid;
            else l = mid;
        }
        System.out.printf("%f",l);
    }
}

三、前缀和与差分

1.前缀和(一维)

原数组:a1, a2, a3 ,...,a4

前缀和:Si = a1+a2+a3+...+a4

问题:

1.求Si=Si-1 + ai

2.求a[l, r] -> Sr - Sl-1  

注意:定义S0 = 0;[1, 10]->S10-S0

题目:795.子矩阵的和

c++题解

Java题解

import java.util.Scanner;

public class qianZhuiHe {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        int[] a = new int[n+1];//记得定义n+1,注意越界
        int[] s = new int[n+1];
        
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }

        for (int i = 1; i <= n ; i++) {
            s[i] = s[i-1] + a[i];//i-1
        }

        while (m-- != 0){  //输入m行,接收要在循环内
            int l = sc.nextInt();
            int r = sc.nextInt();
            int ans = s[r] - s[l-1];
            System.out.println(ans);
        }
    }
}

2.前缀和(二维)

求和(求右下角面积):

求除去右下角之外的面积(Sij的推导方法):

题目:796.子矩阵的和

c++题解

import java.util.Scanner;

public class QianZhuiHe2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int q = sc.nextInt();
        int[][] a = new int[n + 1][m + 1];
        int[][] s = new int[n + 1][m + 1];

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                a[i][j] = sc.nextInt();
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
            }
        }

        while (q-- != 0) {
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();
            int ans = s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1];
            System.out.println(ans);
        }
    }
}

3.差分

bl+c  br+1-c

题目:797.差分

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值