AcWing算法基础课复习——(一)基础算法

一、快速排序

AcWing 785. 快速排序

代码:

import java.io.*;
import java.util.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n;
    static int N=100010;
    static int a[]=new int[N];
    public static void quick_sort(int a[],int l,int r){
        if(l>=r) return;
        int x=a[l+r>>1],i=l-1,j=r+1;
        while (i<j){
            do i++;while (a[i]<x);
            do j--;while (a[j]>x);
            if(i<j){
                int t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
        quick_sort(a,l,j);
        quick_sort(a,j+1,r);
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        quick_sort(a,0,n-1);
        for(int i=0;i<n;i++) pw.print(a[i]+" ");
        pw.close();
    }
}


AcWing 786. 第k个数

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,k;
    static int N=100010;
    static int a[]=new int[N];
    public static void quick_sort(int a[],int l,int r){
        if(l>=r) return;
        int x=a[l+r>>1],i=l-1,j=r+1;
        while (i<j){
            do i++;while (a[i]<x);
            do j--;while (a[j]>x);
            if(i<j){
                int t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
        quick_sort(a,l,j);
        quick_sort(a,j+1,r);
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        k=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        quick_sort(a,0,n-1);
        pw.println(a[k-1]);
        pw.close();
    }
}


二、归并排序

AcWing 787. 归并排序

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,k;
    static int N=100010;
    static int a[]=new int[N];
    static int temp[]=new int[N];
    public static void merge_sort(int a[],int l,int r){
        if(l>=r) return;
        int mid=l+r>>1;
        merge_sort(a,l,mid);
        merge_sort(a,mid+1,r);
        int i=l,j=mid+1,k=0;
        while (i<=mid && j<=r){
            if(a[i]<=a[j]) temp[k++]=a[i++];
            else temp[k++]=a[j++];
        }
        while (i<=mid) temp[k++]=a[i++];
        while (j<=r) temp[k++]=a[j++];
        for(i=l,j=0;i<=r;i++,j++) a[i]=temp[j];
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        merge_sort(a,0,n-1);
        for(int i=0;i<n;i++) pw.print(a[i]+" ");
        pw.close();
    }
}


AcWing 788. 逆序对的数量

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,k;
    static int N=100010;
    static int a[]=new int[N];
    static int temp[]=new int[N];
    public static long merge_sort(int a[],int l,int r){
        if(l>=r) return 0;
        int mid=l+r>>1;
        long ans=merge_sort(a,l,mid)+merge_sort(a,mid+1,r);
        int i=l,j=mid+1,k=0;
        while (i<=mid && j<=r){
            if(a[i]<=a[j]) temp[k++]=a[i++];
            else{
                temp[k++]=a[j++];
                ans+=mid-i+1;
            }
        }
        while (i<=mid) temp[k++]=a[i++];
        while (j<=r) temp[k++]=a[j++];
        for(i=l,j=0;i<=r;i++,j++) a[i]=temp[j];
        return ans;
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        long res=merge_sort(a,0,n-1);
        pw.println(res);
        pw.close();
    }
}


三、二分

AcWing 789. 数的范围

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,q;
    static int N=100010;
    static int a[]=new int[N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        q=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        while (q--!=0){
            int x=nextInt();
            int l=0,r=n-1;
            while (l<r){
                int mid=l+r>>1;
                if(a[mid]>=x) r=mid;
                else l=mid+1;
            }
            if(a[r]==x){//数组中存在x
                pw.print(r+" ");//输出左端点
                r=n-1;
                while (l<r){
                    int mid=l+r+1>>1;
                    if(a[mid]<=x) l=mid;
                    else r=mid-1;
                }
                pw.println(r);//输出右端点
            }
            else pw.println(-1+" "+-1);//数组中不存在x
        }
        pw.close();
    }
}


AcWing 790. 数的三次方根

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static double nextDouble() throws IOException{
        st.nextToken();
        return st.nval;
    }
    static double n;
    public static void main(String args[]) throws IOException{
        n=nextDouble();
        double l=-10000,r=10000;
        while (r-l>1e-8){
            double mid=(l+r)/2;
            if(Math.pow(mid,3)>=n) r=mid;
            else l=mid;
        }
        pw.printf("%.6f",r);
        pw.close();
    }
}


四、高精度

AcWing 791. 高精度加法

代码:

//高精度问题 java中有大数类可以直接用

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;

public class Main {
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(System.out);
    public static void main(String args[]) throws IOException{
        BigInteger a=new BigInteger(bf.readLine());
        BigInteger b=new BigInteger(bf.readLine());
        BigInteger res=a.add(b);
        pw.println(res);
        pw.close();
    }
}


AcWing 792. 高精度减法

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;

public class Main {
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(System.out);
    public static void main(String args[]) throws IOException{
        BigInteger a=new BigInteger(bf.readLine());
        BigInteger b=new BigInteger(bf.readLine());
        BigInteger res=a.subtract(b);
        pw.println(res);
        pw.close();
    }
}


AcWing 793. 高精度乘法

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;

public class Main {
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(System.out);
    public static void main(String args[]) throws IOException{
        BigInteger a=new BigInteger(bf.readLine());
        BigInteger b=new BigInteger(bf.readLine());
        BigInteger res=a.multiply(b);
        pw.println(res);
        pw.close();
    }
}


AcWing 794. 高精度除法

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;

public class Main {
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(System.out);
    public static void main(String args[]) throws IOException{
        BigInteger a=new BigInteger(bf.readLine());
        BigInteger b=new BigInteger(bf.readLine());
        BigInteger res1=a.divide(b);
        BigInteger res2=a.mod(b);
        pw.println(res1);
        pw.println(res2);
        pw.close();
    }
}


五、前缀和与差分

AcWing 795. 前缀和

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,m;
    static int N=100010;
    static int a[]=new int[N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        for(int i=1;i<=n;i++){
            a[i]=nextInt();
            a[i]+=a[i-1];
        }
        while (m--!=0){
            int l=nextInt();
            int r=nextInt();
            pw.println(a[r]-a[l-1]);
        }
        pw.close();
    }
}


AcWing 796. 子矩阵的和

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,m,q;
    static int N=1010;
    static int a[][]=new int[N][N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        q=nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=nextInt();
                a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
            }
        }
        while (q--!=0){
            int x1=nextInt();
            int y1=nextInt();
            int x2=nextInt();
            int y2=nextInt();
            pw.println(a[x2][y2]-a[x2][y1-1]-a[x1-1][y2]+a[x1-1][y1-1]);
        }
        pw.close();
    }
}


AcWing 797. 差分

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,m;
    static int N=100010;
    static int a[]=new int[N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        for(int i=1;i<=n;i++) a[i]=nextInt();
        for(int i=n;i>=1;i--) a[i]-=a[i-1];//差分数组
        while (m--!=0){
            int l=nextInt();
            int r=nextInt();
            int c=nextInt();
            a[l]+=c;
            a[r+1]-=c;
        }
        for(int i=1;i<=n;i++){
            a[i]+=a[i-1];
            pw.print(a[i]+" ");
        }
        pw.close();
    }
}


AcWing 798. 差分矩阵

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,m,q;
    static int N=1010;
    static int a[][]=new int[N][N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        q=nextInt();
        for(int i=1;i<=n;i++){//a的差分矩阵
            for(int j=1;j<=m;j++){
                int x=nextInt();
                a[i][j]+=x;
                a[i][j+1]-=x;
                a[i+1][j]-=x;
                a[i+1][j+1]+=x;
            }
        }
        while (q--!=0){
            int x1=nextInt();
            int y1=nextInt();
            int x2=nextInt();
            int y2=nextInt();
            int c=nextInt();
            a[x1][y1]+=c;
            a[x1][y2+1]-=c;
            a[x2+1][y1]-=c;
            a[x2+1][y2+1]+=c;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
                pw.print(a[i][j]+" ");
            }
            pw.println();
        }
        pw.close();
    }
}


六、双指针算法

AcWing 799. 最长连续不重复子序列

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n;
    static int N=100010;
    static int a[]=new int[N];//原数组
    static int s[]=new int[N];//记录数出现的次数
    public static void main(String args[]) throws IOException{
        n=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        int res=0;
        for(int i=0,j=0;i<n;i++){
           s[a[i]]++;
           while (s[a[i]]>1){
               s[a[j]]--;
               j++;
           }
           res= Math.max(res,i-j+1);
        }
        pw.println(res);
        pw.close();
    }
}


AcWing 800. 数组元素的目标和

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,m,x;
    static int N=100010;
    static int a[]=new int[N];
    static int b[]=new int[N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        x=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        for(int i=0;i<m;i++) b[i]=nextInt();
        for(int i=0,j=m-1;i<n;i++){
            while (a[i]+b[j]>x){
                j--;
            }
            if(a[i]+b[j]==x){
                pw.println(i+" "+j);
                break;
            }
        }
        pw.close();
    }
}


AcWing 2816. 判断子序列

代码:

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static int n,m;
    static int N=100010;
    static int a[]=new int[N];
    static int b[]=new int[N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        for(int i=0;i<n;i++) a[i]=nextInt();
        for(int i=0;i<m;i++) b[i]=nextInt();
        int i=0,j=0;
        while (i<n && j<m){
            if(a[i]==b[j]) i++;
            j++;
        }
        if(i==n) pw.println("Yes");
        else pw.println("No");
        pw.close();
    }
}


七、位运算

AcWing 801. 二进制中1的个数

代码:

// lowbit(x)函数:返回x的二进制表示中的最后一个1及其后面0所组成的数
// 以10为例: 10的二进制为1010 因此lowbit(10)=二进制的10=2;
// 以24为例: 24的二进制为11000 因此lowbit(24)=二进制的1000=8;

import java.io.*;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    public static int lowbit(int x){
        return x&-x;
    }
    static int n;
    public static void main(String args[]) throws IOException{
        n=nextInt();
        for(int i=0;i<n;i++){
            int x=nextInt();
            int res=0;
            while (x!=0){
                x-=lowbit(x);
                res++;
            }
            pw.print(res+" ");
        }
        pw.close();
    }
}


八、离散化

AcWing 802. 区间和

代码:

//离散化: 值域范围很大,但个数很少,对每个x进行映射
//例例如:  0 2 10 500 3000 60000 900000
//映射为:  0 1 2   3   4    5      6

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static class node{
        int x,y;
        public node(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
    static List<node> add =new ArrayList<>();//存储添加操作
    static List<node> query =new ArrayList<>();//存储查询操作
    static List<Integer> all =new ArrayList<>();//存储add,query用到的所有下标
    static int n,m;
    static int N=300010;//有100000个add,每次操作一个下标;有100000个querty,每次操作两个下标;因此需要开3000010;
    static int a[]=new int[N];
    public static int unique(List<Integer> list){//去重,并返回不重复元素的个数
        int j=0;
        for(int i=0;i<list.size();i++){
            if(i==0 || list.get(i)!=list.get(i-1)){
                list.set(j,list.get(i));
                j++;
            }
        }
        return j;
    }
    public static int find(int x,List<Integer> list){//返回list中值为x的下标
        int l=0,r=list.size()-1;
        while (l<r){
            int mid=l+r>>1;
            if(list.get(mid)>=x) r=mid;
            else l=mid+1;
        }
        return r+1;//由于需要用到前缀和,因此下标从1开始
    }
    public static void main(String args[]) throws IOException{
        n=nextInt();
        m=nextInt();
        while (n--!=0){
            int x=nextInt();
            int c=nextInt();
            add.add(new node(x,c));
            all.add(x);
        }
        while (m--!=0){
            int l=nextInt();
            int r=nextInt();
            query.add(new node(l,r));
            all.add(l);
            all.add(r);
        }

        Collections.sort(all);//排序
        int unique=unique(all);//去重
        all=all.subList(0,unique);//保留不重复元素部分

        for(node t:add){//处理add操作
            int index=find(t.x,all);//找到p.x在all中的下标
            a[index]+=t.y;
        }

        for(int i=1;i<=all.size();i++) a[i]+=a[i-1];//前缀和公式

        for(node t:query){//处理查询操作
            int l=find(t.x,all);
            int r=find(t.y,all);
            pw.println(a[r]-a[l-1]);
        }
        pw.close();
    }
}


九、区间合并

AcWing 803. 区间合并

代码:

//区间合并: 快速将有交集的区间进行合并
//贪心思想: 将所有区间按左端点大小进行排序,依次进行判断

import java.io.*;
import java.util.Arrays;

public class Main {
    static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter pw=new PrintWriter(System.out);
    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
    static class node implements Comparable<node>{
        int l,r;
        public node(int l,int r){
            this.l=l;
            this.r=r;
        }
        public int compareTo(node p){
            return Integer.compare(l,p.l);
        }
    }
    static int n;
    static int N=100010;
    static node p[]=new node[N];
    public static void main(String args[]) throws IOException{
        n=nextInt();
        for(int i=0;i<n;i++){
            int l=nextInt();
            int r=nextInt();
            p[i]=new node(l,r);
        }
        Arrays.sort(p,0,n);
        int end=(int)-2e9;//end初始化为负无穷
        int res=0;
        for(int i=0;i<n;i++){
            if(p[i].l>end) res++;//说明两个区间无交集,res++
            end= Math.max(end,p[i].r);//更新end
        }
        pw.println(res);
        pw.close();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值