蓝桥杯算法模板常用套路及API等个人总结

写这篇博客的今天是19年的省赛考前的最后一天了,想写一些小白萌新们受益的东西

 

从最常考的全排列开始吧~

全排列模板1,最常用的写法

public class 全排列_模板1 {

	public static void main(String[] args) {
		dfs(0);
		System.out.println(ans);//9的全排有362880种
	}
	
	static int[] a = new int[] {1,2,3,4,5,6,7,8,9};
	
	static int n=9,ans=0;
	
	static void dfs(int m) {
		if(m>=n) {
			System.out.println("一些核心的操作 比如ans:"+ans);
			ans++;
			for(int i=0;i

 

全排列模板2,使用标记数组的写法

public class 全排列_模板2 {

	public static void main(String[] args) {
		vis = new boolean[n];
		b = new int[n];
		dfs(0);
		System.out.println(ans);//9的全排有362880种
	}
	
	static int[] a = new int[] {1,2,3,4,5,6,7,8,9};
	static int[] b;
	static boolean[] vis;
	static int n=9,ans=0;
	
	static void dfs(int m) {
		if(m>=n) {
			System.out.println("一些核心的操作 比如ans:"+ans);
			ans++;
			for(int i=0;i

 

下面是需要排重的全排_模板

在上面模板上使用了哈希表查重,把一些数组并接成字符串

import java.util.HashSet;

public class 全排列_模板3 {

	public static void main(String[] args) {
		dfs(0);
		System.out.println(ans);//9的全排有362880种
		System.out.println(set.size());//1680
	}
	
	static int[] a = new int[] {1,1,1,2,2,2,3,3,3};
	
	static int n=9,ans=0;
	static HashSet set = new HashSet<>();
	
	static void dfs(int m) {
		if(m>=n) {
			System.out.println("一些核心的操作 比如ans:"+ans);
			ans++;
			String s="";
			for(int i=0;i

 

使用哈希表查重后是无序的,那么遇到需要打印字典序的有重复元素的全排呢

leetcode 46. 全排列

leetcode 47. 全排列 II

子集的写法也和全排很相似

leetcode 78. 子集(Subsets) beat 100%

leetcode 90. 子集 II(Subsets II) beat 98.57%

 

 

 

判断闰年

	static boolean is(int x) {
		return x%400==0 || (x%4==0 && x%100!=0);
	}

 

 

筛素数O({\color{DarkBlue} n^{\tfrac{3}{2}}})

	static boolean is(int n) {
		if(n==1)
			return false;
		for(int i=2;i*i<=Math.sqrt(n);i++)
			if(n%i==0)
				return false;
		
		return true;
	}

 

倍筛法_素数O(nlogn)

public class 倍筛模板 {

	public static void main(String[] args) {
		boolean[] is = new boolean[1000005];
		is[1] = true;//true表示不是素数
		for(int i=2;i<1000005;i++)
			if(!is[2])
				for(int j=2*i;j<1000005;j+=i)
					is[j] = true;
		System.out.println(is[2004]);
	}

}

 

01背包

public class _01背包 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int m = in.nextInt();//大小
		int n = in.nextInt();//物品数
		int[] dp = new int[m+5];//开背包质量的大小
		for(int i=1;i<=n;i++) {
			int v = in.nextInt();//物品体积
			int w = in.nextInt();//物品价值
			for(int j=m;j>=v;j--)
				dp[j] = Math.max(dp[j], dp[j-v]+w);
		}
		System.out.println(dp[m]);
	}

}

 

完全背包

import java.util.Scanner;

public class _完全背包 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int m = in.nextInt();//大小
		int n = in.nextInt();//物品数
		int[] dp = new int[m+5];//开背包质量的大小
		for(int i=1;i<=n;i++) {
			int v = in.nextInt();//物品体积
			int w = in.nextInt();//物品价值
			for(int j=v;j<=m;j++)
				dp[j] = Math.max(dp[j], dp[j-v]+w);
		}
		System.out.println(dp[m]);
	}

}

 

 

最小公倍数gcd

	static int gcd(int a,int b) {
		return b==0?a:gcd(b,a%b);
	}

最大公约数lcm

	static int lcm(int a,int b) {
		return a*b/gcd(a,b);
	}

多个数共同的gcd和lcm模板

	static int gcd(int[] a) {
		int n = a.length;
		int g = a[0];
		for(int i=1;i

二分答案_模板

蓝桥杯 2017年第八届真题 分巧克力 经典的二分答案 输入挂

	static void f(int[] a) {
		int n = a.length;
		int l=0,r=n-1,ans=0;//一般上界需要自己构造
		while(l<=r) {
			int mid = l + (r-l)/2;
			if(ok(a[mid])) {
				r = mid-1;
				ans = mid;
			}else
				l = mid+1;
		}
		System.out.println(ans);
	}
	
	static boolean ok(int x) {
		return false;//按照题意写
	}

二分lower_bound的实现(找到第一个大于等于给定值key的那个数)如[1,2,2,3]查找2,会返回第一个2的下标

    public static int lowerBound(int []nums,int l,int r,int target){
        while(l<=r){//r=n-1
            int m = (l+r)/2;
            if(nums[m]>=target) r= m-1;
            else    l = m +1;
        }
        return l;
    }

upper_bound的实现(要求在按照非递减顺序排好序的数组中找到第一个大于给定值key的那个数)(不常用)

    public static int upperBound(int []nums ,int l,int r, int target){
        while(l

 

各种排序实现

  • 冒泡排序(学会手写)
  • 选择排序(没什么应用)
  • 插入排序(对近乎有序的数组复杂度提升到O(n))
  • 计数排序(给定区间排序)
  • 归并排序(求逆序数)
  • 快速排序(找第K大数)
  • 堆排序(优先队列API)
  • 希尔排序(插入排序的升级版)

 

大数类BigInteger和BigDecimal及方法API

考场上查API

 

 

进制问题,如有价值1,2,4,8等价值的硬币,如何用最小的硬币数凑出100元

	static int f(int n,int k) {//调用API转成k进制,缺点题目有上界为8
		int ans=0;
		String s = Integer.toString(n, k);
		System.out.println(s);
		for(int i=0;i

头条面试题:找钱问题,共1024,64,16,4,1几种面值 

    static void solve(){
        Scanner cin = new Scanner(System.in);
        int N = 1024-cin.nextInt(), ans = 0;
        for(int i=0; i<4; i++){
            ans += N/arr[i];
            N %= arr[i];
        }
        System.out.println(ans);
    }
!

堆的应用,给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效

leetcode 20. 有效的括号(Valid Parentheses)

    public boolean isValid(String s) {
    	if(s==null||s.equals(""))
    		return true;
 
        char[] ch = s.toCharArray();
        Stack stack = new Stack<>();
        
        for(int i=0;i

 

快速幂及矩阵快速幂模板

矩阵幂_快速幂_矩阵乘法_模板

	static long mpow(long a,long n) {//快速幂,mod一般题目给1e9+7
		if(n==0 || a==1)
			return 1;
		long ans=1;
		while(n!=0) {
			if(n%2==1)
				ans = a*ans%mod;
			a=a*a%mod;
			n>>=1;
		}
		
		return ans;
	}

 矩阵乘法模板

//这里是矩阵的乘法模板,默认方阵
	static int[][] mul(int[][] a,int[][] b){
		int n = a.length;
		int[][] ans = new int[n][n];
		for(int i=0;i

 矩阵快速幂模板


	//矩阵快速幂_模板
	static int[][] mpow(int[][] a,int n){
		int N = a.length;
		int[][] ans = new int[N][N];
		for(int i=0;i0) {//写 n!=0也行,会快些么,反正位运算是会快的.这个不清楚
			if((n&1)==1) 
				ans = mul(ans,a);
			a = mul(a,a);
			n>>=1;
		}
		return ans;
	}

 

阶乘逆元求组合数C(n,m)模板_O(nlogn)

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		f = new long[n+5];
		inv = new long[n+5];
		f[0]=1;
		for(int i=1;i>=1;
		}
		
		return ans;
	}

 

 

欧拉函数模板        定义:小于n的正整数中与n互质的数的数目(φ(1)=1)

	static int Euler(int n) {//O(n) 有时候需要long
		int ans=n;
		
		for(int i=2;i<=n;i++) 
			if(n%i==0) {
				ans=ans/i*(i-1);
				while(n%i==0)
					n/=i;
			}
		
		return ans;
	}
	static int Euler(int n) {//O(sqrt(n))
		int ans=n;

		for(int i=2;i*i<=n;i++) 
			if(n%i==0) {
				ans=ans/i*(i-1);////n*(1-(1/p))转化为n/p*(p-1)
				while(n%i==0)
					n/=i;
			}
		if(n>1)//优化 O(sqrt(n)) 不过要在出口 if(n>1)ans/n*(n-1) O(n)不用
			ans=ans/n*(n-1);
		
		return ans;
	}

 

前缀和模板

import java.util.Scanner;

public class 前缀和模板 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] sum = new int[n+1];
		for(int i=1;i<=n;i++)
			sum[i] = sum[i-1] + in.nextInt();//前i个数的和

	}

}

 

线段树模板

 

 

并查集模板

	static int n,m,cnt=0;
	static int[] f = new int[10005];//初始化一般是f[i]=i
	
	static int find(int x) {
		if(f[x]==x)
			return x;
		return f[x] = find(f[x]);
	}
	
	static void union(int x,int y) {
		int a = find(x);
		int b = find(y);
		if(a!=b) {
			f[a] = b;
			cnt++;
		}
	}

 

dfs求联通块模板

	static int n,m;
	static int[][] vis;
	static char[][] ch;

	static int[] dx = new int[] {1,1,1,0,0,-1,-1,-1};
	static int[] dy = new int[] {0,-1,1,1,-1,1,0,-1};
	
	static void dfs(int t,int x,int y) {// hdu1241 油田问题 八联通
		vis[x][y] = t;
		
		for(int i=0;i<8;i++) 
			if(x+dx[i]>=0 && x+dx[i]=0 && y+dy[i]
			int t=0;
			for(int i=0;i

最小生成树模板

	static int n,m,cnt=0,ans=0;
	static int[] f;
	
	static int find(int x) {
		if(f[x]==x)
			return x;
		return f[x] = find(f[x]);
	}
	
	static int union(int x,int y) {
		int a = find(x);
		int b = find(y);
		if(a!=b) {
			f[a] = b;
			return 1;
		}
		return 0;
	}
	
	
	static class Edge implements Comparable{
		int a,b,c;
		public Edge(int a,int b,int c) {
			this.a = a;
			this.b = b;
			this.c = c;
		}
		@Override
		public int compareTo(Edge o) {
			return this.c - o.c;
		}
	}
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);  //用它来代替Scanner。
		while(true) {
			n = in.nextInt();
			if(n==0)
				break;
			m = n*(n-1)/2;
			cnt=0;
			ans=0;
			f = new int[n+5];
			for(int i=1;i<=n;i++)
				f[i] = i;
			
			PriorityQueue pq = new PriorityQueue<>();
			
			for(int i=1;i<=m;i++) {
				int a = in.nextInt();
				int b = in.nextInt();
				int c = in.nextInt();
				int d = in.nextInt();
				if(d==1)
					cnt+=union(a,b);
				else
					pq.add(new Edge(a, b, c));
			}
			
			while(!pq.isEmpty()) {
				Edge u = pq.poll();
				if(union(u.a, u.b)==1) {
					cnt++;
					ans+=u.c;
					if(cnt==n-1)
						break;
				}
			}
			
			System.out.println(ans);
		}
		
		
	}

输入挂模板

	//解决javaIO读取过慢的方法,利用该类读取输入数据,不要用Scanner!!!
	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream), 32768);
			tokenizer = null;
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

	}

 

拓扑排序模板

蓝桥杯 卡勒沃夫之弱水路三千(提高型) 拓扑排序+Map

		static ArrayList list = new ArrayList<>();
	    static ArrayList[] edge = new ArrayList[105];	
        
		while(m-->0) {//建图 邻接表 并且用w[i]记录入度
			String s1 = in.next();
			String s2 = in.next();
			if(!map.containsKey(s1))
				map.put(s1,n++);
			if(!map.containsKey(s2))
				map.put(s2,n++);
			w[map.get(s2)]++;
			edge[map.get(s1)].add(map.get(s2));
		}

    	for(int i:map.values())//把边为0的放进队列
				if(w[i]==0)
					q.add(i);
			while(!q.isEmpty()) {
				int u = q.poll();
				list.add(u);
				for(int v:edge[u]) {
					w[v]--;
					if(w[v]==0)
						q.add(v);
				}
			}

dijkstra模板O(n^2)

 

 

dijkstra邻接表+优先队列模板O(nlogn)

 

 

 

 

 

 

 

 

你可能感兴趣的:(蓝桥杯)