蓝桥杯常用算法模板---基础篇

写在前面:距离蓝桥杯省赛还有不到半月,个人整理一些常用算法,分享给大家。

最小公倍数gcd、最大公约数lcm

public class LeastCommonMultiple {
    //使用欧几里得算法求解数m和数n最大公约数
    public int getGcd(int m,int n){
        while(n > 0){
            int temp = m % n;
            m = n;
            n = temp;
        }
        return m;
    }
    
    //求解数m和n和最小公倍数
    public int getLcm(int m,int n){
        int gcd = getGcd(m,n);
        int result = m*n / gcd;
        return result;
    }

多个数共同的gcd和lcm模板

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

保留小数点

方法一:使用Math.round()函数,此处返回的是数字格式

float f=1.258;
int i=3;
float t=f*i;
float num=(float)(Math.round(t*100)/100.0);//如果要求精确4位就*10000然后/10000

方法二:使用DecimalFormat包,此处返回的是string类型

import java.text.DecimalFormat;
sum = 1.55555	//计算最终分数
DecimalFormat decimalFormat=new DecimalFormat(".00");	//如果小数不足2位,会以0补足.
String p=decimalFormat.format(sum);

java:Java的取整函数

//Math.floor()、Math.ceil()、BigDecimal都是Java中的取整函数,但返回值却不一样

Math.floor()

通过该函数计算后的返回值是舍去小数点后的数值

如:Math.floor(3.2)返回3

Math.floor(3.9)返回3

Math.floor(3.0)返回3

Math.ceil()

ceil函数只要小数点非0,将返回整数部分+1如:Math.ceil(3.2)返回4

Math.ceil(3.9)返回4

Math.ceil(3.0)返回3 

判断闰年

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

筛选素数

boolean isprime(int n){
	if(n==1)return false;
	for(int i=2;i*i

时间差(日期)

public class Test {
public void dateDiff(String startTime, String endTime, String format) {
//按照dao传入的格式生成一个simpledateformate对象
SimpleDateFormat sd = new SimpleDateFormat(format);
long nd = 1000*24*60*60;//一天的毫秒数
long nh = 1000*60*60;//一小时的毫秒数
long nm = 1000*60;//一分钟的毫秒数
long ns = 1000;//一秒钟的毫秒数long diff;try {
//获得两个时间的毫秒时间差异
diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
long day = diff/nd;//计算差多少天
long hour = diff%nd/nh;//计算差多少小时
long min = diff%nd%nh/nm;//计算差多少分钟
long sec = diff%nd%nh%nm/ns;//计算差多少秒//输出结果
System.out.println("时间相差:"+day+"天"+hour+"小时"+min+"分钟"+sec+"秒。"); 

 字符串中特定字串出现的次数

public class TestIndexOf {
 	public static void main(String[] args) {
 		 int num = getMaches("abcabcabcabca", "ca");
 		 System.out.println(num);
 }
 
	 public static int getMaches(String str,String substr){
  		int count = 0;//count用来接收子字符串substr在字符串str中出现的次数
 		int i = 0;
 		while(str.indexOf(substr,i) != -1) {
   		 	count++;
  			 i=str.indexOf(substr, i)+substr.length();
		  }
	 	 return count;
	 }
}

二分答案模板

	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;//按照题意写
	}

快速幂

static int mod=100000007;
	/**
	 * 计算a的n次方(要求n>=0)
	 * @param a
	 * @param n
	 * @return
	 */
	public static long quickPow(long a,int n) {
		
		long ans=1;
		while(n>0) {
			if((n&1)==1)
				ans=ans*a%mod;
			a=a*a%mod;
			n>>=1;
			
		}
		return ans;
		
	}

背包问题

简单背包


import java.util.Scanner;
/*
* 有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大
特点  但它的特点是每个物品只能选用一次
* */
 
public class situation01 {
    //01背包
    public static void main(String args[]){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();//物品的总数量
        int m = scanner.nextInt();//背包的重量
        int a[] = new int[50001];//重量
        int b[] = new int[50001];//价值
        for (int i=1;i<=n;i++){
            a[i] = scanner.nextInt();
            b[i] = scanner.nextInt();
        }
        int f[] = new int[50001];
        for (int i=1; i<=n; i++){
            for (int j=m; j>=a[i]; j--){//完全背包只修改了这一句的顺序,其余不变for(int j=a[i]; j<=m; j++)
                if (f[j-a[i]]+b[i]>f[j])//多重背包就是在a[i]和b[i]前面加了数量
                    f[j] = f[j-a[i]]+b[i];
            }
        }
        System.out.println(f[m]);
    }
}

完全背包


import java.util.Scanner;
 
/*
* 有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大
特点 题干看似与01一样 但它的特点是每个物品可以无限选用
* */
public class situation02 {
     public static void main(String args[]){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();//物品的数量
        int m = scanner.nextInt();//背包的重量
        int a[] = new int[50001];
        int b[] = new int[50001];
        for (int i=1;i<=n;i++){
            a[i] = scanner.nextInt();
            b[i] = scanner.nextInt();
        }
        int f[] = new int[50001];
        for (int i=1; i<=n; i++){
            for (int j=a[i]; j<=m; j++){//完全背包只修改了这一句的顺序,其余不变for(int j=a[i]; j<=m; j++)
                if (f[j-a[i]]+b[i]>f[j])
                    f[j] = f[j-a[i]]+b[i];
            }
        }
        System.out.println(f[m]);
    }
}

多重背包

import java.util.Scanner;
 
import static sun.swing.MenuItemLayoutHelper.max;
 
public class situation03 {
    /*
    * 多重背包
    * 每件物品可以选择有限的次数
    * */
    public static void main(String args[]){
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();//背包的重量
        int n = scanner.nextInt();//物品的总数量
        int[] a = new int[10001];//重量
        int[] b = new int[10001];//价值
        int[] c = new int[10001];//数量
        for (int i=0; i=0; j--){
                for (int k=0; k<=c[i]; k++){
                    if (j-k*a[i]<0) break;
                    f[j]= max(f[j],f[j-k*a[i]]+k*b[i]);
                }
            }
        }
        System.out.println(f[m]);
    }
}

DFS

import java.awt.*;
import java.util.ArrayList;


public class DFS {

static int maxn=100;
    static boolean vst[][]  = new boolean[maxn][maxn]; // 访问标记
    static int map[][] = new int[maxn][maxn]; // 坐标范围
    ArrayList dir = new ArrayList<>(); //方向向量,(x,y)周围的四个方向

   public static boolean CheckEdge(int x,int y) //边界条件和约束条件的判断
    {
        if(!vst[x][y] && ) // 满足条件
        return true;
    else // 与约束条件冲突
        return false;
    }

    void dfs(int x,int y)
    {
        vst[x][y]=true; // 标记该节点被访问过
        if(map[x][y]==) // 出现目标态G
        {
        ...... // 做相应处理
            return;
        }
        for(int i=0; i<4; i++)
        {
            if(CheckEdge(x+dir[i][0],y+dir[i][1])) // 按照规则生成下一个节点
                dfs(x+dir[i][0],y+dir[i][1]);
        }
        return; // 没有下层搜索节点,回溯
    }

    public static void main(String[] args)
    {

    }

}

BFS

// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue q; // 核心数据结构
    Set visited; // 避免走回头路
    
    q.offer(start); // 将起点加入队列
    visited.add(start);
    int step = 0; // 记录扩散的步数

    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
            Node cur = q.poll();
            /* 划重点:这里判断是否到达终点 */
            if (cur is target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj())
                if (x not in visited) {
                    q.offer(x);
                    visited.add(x);
                }
        }
        /* 划重点:更新步数在这里 */
        step++;
    }
}

不带重复元素的重排列

import java.util.Scanner;

public class Main{
    static int N = 10, n ;
    static boolean st[] = new boolean[N];
    static int[] f = new int[N];
    
    public static void dfs(int u){
        if( u == n){
            for(int i = 0; i < n; i ++)
                System.out.print(f[i]+" ");
            System.out.println();
            return;
        }
        for(int i = 1; i <= n; i++)
            if(!st[i]){
                st[i] = true;
                f[u] = i;
                dfs( u + 1);
                st[i] = false;
                
            }
    }
    
    public static void main(String args[]){
        Scanner reader = new Scanner(System.in);
        n = reader.nextInt();
        dfs(0);
    }
}

带重复元素的全排列

import java.util.Scanner;
import java.util.Arrays;
/*
带重复元素的全排列
*/
public class Main{
    //1 2 2 3 3
    
    static int a[]= {2,1,2};
    static int n = a.length;
    static boolean st[] = new boolean[n];
    static int [] f=  new int[n];
    
    public static void dfs(int u){
        if( u == n){
            for(int i = 0; i < n; i ++)
                System.out.print(f[i]+" ");
            System.out.println();
            return;
        }
        for(int i = 0; i < n; i ++){
            if( !st[i]){
                //当前元素与前一个元素相同 且 前一个元素没有用过 
                if( i > 0 && a[i] == a[i - 1] && !st[i - 1]) continue;
                st[i] = true;
                f[u] = a[i];
                dfs( u + 1);
                st[i] = false;
            }

        }
            
    }
    public static void main(String args[]){
        //Scanner reader = new Scanner(System.in);
        //n = reader.nextInt();
        Arrays.sort(a, 0, n);
        dfs(0);
    }
}

              最长上升子序列

import java.util.Scanner;
 
public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in); 
		int n = sc.nextInt();
		int[] arr = new int[10002];//arr数组表示输入的序列
		int[] dp = new int[10002];//dp数组中存放上升序列的长度,dp[i]表示以arr[i]结尾的子序列的最大长度
		for(int i = 1;i <= n;i++) {//输入序列
			int a = sc.nextInt();
			arr[i] = a;
		}
		
		int result = -1;//记录dp中最大的值
		
		for(int i = 1;i <= n;i++) {//按顺序计算dp[i]的值
			dp[i] = 1;//假设该子序列中只有arr[i],故长度为1,即其自身成为一个子序列
			for(int j = 1;j < i;j++) {
//如果在i之前有比arr[i]小的数(arr[j]),并且把该数(arr[i])放到以arr[j]结尾的子序列末尾后,
//其长度比当前以arr[i]结尾的子序列长度要长
				if(arr[i] > arr[j] && dp[j] + 1 > dp[i]) {
					dp[i] = dp[j] + 1;//把arr[i]放到以arr[j]结尾的子序列之后,原来的长度+1
				}
			}
			result = Math.max(result, dp[i]);//找出在dp数组中最大的一个,即子序列长度最长的一个
		}
		System.out.println(result);
	}
}

你可能感兴趣的:(数据结构与算法,蓝桥杯,java)