当前位置: 首页 > news >正文

蓝桥杯备考

先浅学一遍数据结构,不会拉倒,找点简单题练练语法基础

然后边学边刷二分查找和双指针

递归和暴力,边学边刷

学习贪心,练个几十道

再去过下数据结构

开始算法:搜索,动态规划,

搜索很重要,深度优先可骗分

然后动态规划,挺难,多学多练看造化

一共10道题,填空题,只需要答案 代码题:提交代码 从易到难

一等奖:10% 二等奖20% 三等奖30%

刷题:洛谷 力扣(偏面试) 真题

暴力搜索

深度优先搜索重要

动态规划

前三道题中通常涉及到循环.

  • for循环:可以在题目中找到循环次数
  • while:只知道循环条件

考察循环时,还会涉及到集合,字符串等知识点的应用.例如

  • 对字符串一般考察常用函数.字符串转字符数组,判断结尾等
  • 集合一般考察集合特性: list:有序可重复 set:无序不可重复 map:键值对key-value.

一.必备知识复习

1.集合

2.栈

Stack<> stack = new Stack<>();

先进后出

3.队列

Queue<引用数据类型>queue = new LinkedList<>();

先进先出

4.排序库的使用

5.字符串

//1.将数字转成字符串
String j = i+"";//2.将字符串转成字符串数组
char[] chars = j.toCharArray();//3.对数组进行排序
Arrays.sort(数组);//4.逆序打印
for (int i = chars.length-1; i >=0; i--) {System.out.print(chars[i]);;
}//5.全部转大小写
toLowerCase()/toUpperCase()//6.equals方法
//即使两个字符串对象位于不同的内存位置,只要它们包含相同的字符序列,equals方法也会返回true。//7.使用StringBuffer和StringBuilder的append方法可以轻松的拼接字符串如果字符串存在
大量修改操作,并且单线程,使用StringBuilder 多线程,使用StringBuffer,
可以用到其中的reverse()函数对字符串进行翻转//8. 1byte=8bit   1KB=1024byte   1MB=1024KB  1GB=1024MB//9.通过实现Comparator接口进行自定义排序
Arrays.sort(arr,new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return (o2+o1).compareTo(o1+o2);}
});//10.charAt(i)返回索引为i的字符//11.String类的contains方法它用于检测一个字符串内是否包含
//另一个特定的字符序列(或称为子字符串)//12.常用函数 绝对值函数Math.abs();    整型转字符串 Integer.toString();字符串转整型 Integer.parseInt();//StringBuilder的delete方法 
//作用:删除字符串下标为0的元素(注意此时的0下标的元素改了为下标为1的字符)//主要用到的方法 StringBuilder的append用来拼接到字符串末尾  
//String.charAt(i)取走第i个元素
//sb.indexOf:返回指定字符串第一次出现在字符串中的索引 若没有则返回-1或自己设置的默认值
//sb.subString(index)截取该下标后的字符串
//String.vauleOf()将()转为字符串System.out.printf("%.2f",a);//输出两位小数

1.确定字符串是否是另一个的排列
package com.study.Str;import java.util.Arrays;
import java.util.Scanner;/*
实现一个算法来识别一个字符串 str2str2 是否是另一个字符串 str1str1 的排列。
排列的解释如下:如果将 str1str1 的字符拆分开,重新排列后再拼接起来,
能够得到 str2str2 ,那么就说字符串 str2str2 是字符串 str1str1 的排列。
(不忽略大小写)
如果 str2str2 字符串是 str1str1 字符串的排列,则输出 YES;
如果 str2str2 字符串不是 str1str1 字符串的排列,则输出 NO;*/
public class str2 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//思路 将str1和str2字符串转换为字符数组 然后进行排序 排序后重新赋值给字符串 然后调用equals方法进行比较char[] s1 = scan.next().toCharArray();char[] s2 = scan.next().toCharArray();Arrays.sort(s1);Arrays.sort(s2);String str1 = new String(s1);//传入字符数组也可以创建字符串String str2 = new String(s2);//使用equals方法//即使两个字符串对象位于不同的内存位置,只要它们包含相同的字符序列,equals方法也会返回true。System.out.println(str1.equals(str2)==true?"YES":"NO");scan.close();}
}
2.压缩字符串*
package com.study.Str;import java.util.Arrays;
import java.util.Scanner;//实现一个算法来压缩一个字符串。压缩的要求如下://需要判断压缩能不能节省空间,仅在压缩后字符串比原字符串长度更短时进行压缩。//压缩的格式是将连续相同字符替换为字符 + 数字形式,例如 "AAABCCDDDD" 变为 "A3BC2D4"。
public class str3 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//思路:先将字符串转换成字符数组进行排序 利用计数器进行计数 利用StringBuilder来记录返回的数组String str = scan.next();char[] s = str.toCharArray();Arrays.sort(s);StringBuilder sb =  new StringBuilder();int i=0;int count=1;for(i=0;i<s.length-1;i++) {//length-1防止越界if(s[i]==s[i+1]) {count++;continue;//继续循环 不执行下面的语句}if(count==1) {sb.append(s[i]);}else {sb.append(s[i]).append(count);}//重置计数器count=1;}//添加最后一个元素 出循环时i=length-1即最后一个元素if(count==1) {sb.append(s[i]);}else {sb.append(s[i]).append(count);}if(sb.length()<s.length) {System.out.println(sb);}else {System.out.println("NO");}scan.close();}
}
3.拼数-自定义排序
package com.study.Str;import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;public class str4 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//给定  n 个正整数 a1,a2,…,ana1,a2,…,an,你可以将它们任意排序。//现要将这 n个数字连接成一排,即令相邻数字收尾相接,组成一个数。//问,这个数最大可以是多少。//思路:将数组最左边的一位进行排序 需要用到内部类自定义排序规则//将两个字符串拼接比较排序int n = scan.nextInt();String[] arr = new String[n];for(int i=0;i<n;i++) {arr[i]=scan.next();}Arrays.sort(arr,new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return (o2+o1).compareTo(o1+o2);}});//连接所有字符串StringBuilder sb = new StringBuilder();for(int i=0;i<n;i++) {sb.append(arr[i]);}System.out.println(sb);scan.close();}
}
4.最长回文子串-中心扩展法
public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//思路 通过遍历字符 中心扩散法  String s = scan.next();s=longestPalindrome(s);System.out.println(s.length());scan.close();}public static String longestPalindrome(String s) {//回文长度int maxLen=0;//回文起始位置索引int maxLenS=0;//遍历字符串for(int i=0;i<s.length();i++) {//定义左右指针和该位置的回文长度int left=i-1;int right=i+1;int len=1;//最短回文长度为1//防止越界 以字符数组中心点情况为例 abccbybccaa//开始 i指向y 当i-1等于i时 len++ 指针左移再进行比较(循环+条件) 向右同理while(left>=0&& s.charAt(left)==s.charAt(i)) {left--;len++;}while(right<s.length()&& s.charAt(right)==s.charAt(i)) {right++;len++;}while(left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right)) {left--;right++;len+=2;}//记录最大回文长度 和回文起始位置if(len>maxLen) {maxLen=len;maxLenS=left;}}return s.substring(maxLenS+1, maxLenS+1+maxLen);}
5.反转字符串中的字符-倒序遍历
package com.study.Str;import java.util.Arrays;
import java.util.Scanner;//实现一个算法来实现反转字符数组的功能。反转的要求如下:
//1. 将字符数组的字符进行反转,例如 ['b', ' ', 'a', 'r'] 变成 ['r', 'a', ' ', 'b']。
//2. 将字符数组替换为反转后的数组。
public class str6 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//思路 倒序遍历即可//nextLine()可以读取一整行的内容包括空格char[] arr1 = scan.nextLine().toCharArray();char[] arr2 = new char[arr1.length];for(int i=0;i<arr1.length;i++) {arr2[arr2.length-i-1]=arr1[i];}for(int i=0;i<arr2.length;i++) {System.out.print(arr2[i]);}scan.close();}
}
6.数字反转
package com.study.Str;import java.util.Arrays;
import java.util.Scanner;public class str8 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//转成字符串 然后利用字符串翻转来处理//注意正负数分别处理 利用Math.abs()绝对值函数来处理 int num = scan.nextInt();int num1 = Math.abs(num);String s = Integer.toString(num1);StringBuilder sb = new StringBuilder(s).reverse();int a = Integer.parseInt(sb.toString());if(num<0) {System.out.println(-a);}else {System.out.println(a);}scan.close();}
}

6.时空复杂度分析

计算机1s可以计算10的8次方,要控制代码的时间复杂度在10^8以内

二.算法

1.模拟

用代码模拟题意

package com.study.moni;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();long ans = 0;for(int i=1;i<=n;i++) {String s = i+"";if(s.contains("2")||s.contains("0")||s.contains("1")||s.contains("9")) {ans+=i;}}System.out.println(ans);}
}

2.前缀和

前缀和就是数组中从第一个元素到当前元素之间所有元素的累加和。

前缀和的运用

推导公式: sum[i]=sum[i-1]+a[i-1]

sum[L,R] = sum[R]-sum[L-1]

例题1

package com.study.moni;import java.util.Scanner;public class Main1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//思路 分析出整个式子的规律 sum为a1+...+an//提公因式可以得:S=a1(sum-a1)+a2(sum-a1-a2)+...int n = scan.nextInt();int[] a = new int[n];long sum=0,res=0;for(int i=0;i<n;i++) {a[i]=scan.nextInt();sum+=a[i];}for(int i=0;i<n;i++) {sum-=a[i];res+=sum*a[i];}System.out.println(res );}
}
例题2**97 k倍区间

package com.study.moni;import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;public class Main1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//思路 这是一个前缀和问题 两边区间的和为k的倍数即符合题意//前缀和计算公式:sum[i]=sum[i-1]+arr[i]//前缀和中有一个推导公式适用于本题:  sum[L,R] = sum[R]-sum[L-1]     //即需要找出区间有多少个(sum[R]-sum[L-1])%k==0即是符合条件的//通过双重for循环可以简单找出来/** for(int i=1;i<=n;i++){* 		for(int j=1;j<=i;j++){* 			if((s[i]-s[j-1])%k==0&&(s[i]-s[j-1])>0){*				count++;*			}*		}*}*但双重循环会超时 需要优化掉一个循环 将判断公式变形->s[R]%k==s[L-1]%k*即对前缀和取模后 结果相等的两个前缀和可以构成一个k倍区间*意思就是说对于给定K,如果有任意两个前缀和%K,的结果相等,这时的L和R就能构成一个k倍区间*我们1.使用一个哈希表来存储每个前缀和对 k 取模后的结果及其出现的次数。*2.在遍历数组计算前缀和时,检查当前前缀和对 k 取模后的结果是否在哈希表中已经存在。*3.更新哈希表中前缀和对 k 取模后的结果出现的次数。*/int n=scan.nextInt();int k=scan.nextInt();long count=0;int[] arr = new int[n];long sum=0;Map<Integer,Integer> map = new HashMap<>();map.put(0,1);//初始化 表名前缀和为0的情况有一次for(int i=0;i<n;i++) {arr[i]=scan.nextInt();sum+=arr[i];//计算当前sum%k的结果//还得处理负数情况 int mod = (int)((sum%k+k)%k);//检查之前是否存在 存在就将之前值加上去if(map.containsKey(mod)) {count+=map.get(mod);}//更新哈希表中当前前缀和对k取模后出现的次数	//getOrDefault方法是返回mod这个key对应的值,不存在这个key则返回第二个参数作为默认值map.put(mod,map.getOrDefault(mod, 0)+1);}System.out.println(count);scan.close();//1 1 2 3 4 5//1 2 4 7 11 16}
}
例题3

package com.study.moni;import java.util.Scanner;public class Main2 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n=scan.nextInt();int[] arr = new int[n];for(int i=0;i<n;i++) {arr[i]=scan.nextInt();}int[] sum = new int[n];for(int i=0;i<n;i++)sum[i+1]=sum[i]+arr[i];int  m = scan.nextInt();for(int i=0;i<m;i++) {int l = scan.nextInt()-1;//题目是1-n 减一变为0-nint r = scan.nextInt()-1;System.out.println(sum[r+1]-sum[l]);}}
}

3.二分查找

版本1

将区间[l,r]划分成[l,mid]和[mid+1,r] 其更新操作是r=mid,l=mid+1 计算mid时不需要+1

模板1
int[] arr = {1,2,3,4,5,6};
int left=0,right=arr.length-1;
int k=3;
while(left<right){//left==right退出循环int mid = (left+right)/2;if(arr[mid]>=k)right=mid;else left=mid+1;
}
//数组的区间[0,left-1]满足arr[i]<k
[left,n-1]满足arr[i]>=k
版本2

将区间[l,r]划分成[l,mid-1]和[mid,r]时 更新操作是

模板2
int[] arr = {1,2,3,4,5,6};
int left=0,right=arr.length-1;
int k=3;
while(left<right){//left==right退出循环int mid = (left+right+1)/2;if(arr[mid]>k)right=mid-1;else left=mid;
}
//数组的区间[0,left]满足arr[i]<k
[left+1,n-1]满足arr[i]>11111k
例题1-172递增三元组
import java.util.Scanner;
import java.util.Arrays;
// 1:无需package
// 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//思路 通过二分查找法 找出循环中满足Ai<Bj<Ck的int n =scan.nextInt();int[] a = new int[n];int[] b = new int[n];int[] c = new int[n];for(int i=0;i<n;i++)a[i]=scan.nextInt();for(int i=0;i<n;i++)b[i]=scan.nextInt();for(int i=0;i<n;i++)c[i]=scan.nextInt();Arrays.sort(a);Arrays.sort(b);Arrays.sort(c);int[] B =new int[n];for(int i=0;i<n;i++) {int left=0,right=n-1;while(left<right) {//left==right退出循环int mid = (left+right)/2;if(c[mid]>b[i]) {right=mid;}else {left = mid+1;}}//通过二分查找找出第一个大于b[i]的索引leftif(c[left]>b[i]) {B[i]=n-left;//记录此次循环中满足Ci>Bi的个数=left+n-1+1}}//计算B数组的前缀和long[] sum = new long[n+1];for(int i=1;i<=n;i++) {sum[i]=sum[i-1]+B[i-1];}long ans = 0;//同理找满足Bj>Ai的for(int i=0;i<n;i++) {int left=0,right=n-1;while(left<right) {int mid = (left+right)/2;if(b[mid]>a[i]) {right=mid;}else {left = mid+1;}}if(b[left]>a[i]) {//进来的都是满足条件的ans+=sum[n]-sum[left];//>left索引的都符合即可得到符合条件的个数}}System.out.println(ans);scan.close();}
}
例题2- 99分巧克力
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//思路分析: 通过二分查找找出满足题意的最大边长(类似这种最大问题一般涉及到二分)//问题的解具有单调性 找出这个边长的临界值//输入int n=scan.nextInt();int k=scan.nextInt();int[] h=new int[n];	int[] w=new int[n];	for(int i=0;i<n;i++) {h[i]=scan.nextInt();w[i]=scan.nextInt();}//确定二分查找的上下界int left=1,right=100000;while(left<right) {int mid=(left+right+1)/2;if(check(mid,h,w,k))//如果能切出k块正方形则尝试更大的边长left=mid;else //不能则尝试更小的边长right=mid-1;}System.out.println(left);scan.close();}//判断当前mid是否满足条件 能否切割出k个正方形public static boolean check(int mid,int[]h,int[]w,int k) {int ans=0;for(int i=0;i<h.length;i++) {//属于整除法,分别计算矩形的高度和宽度能够容纳多少个边长为 mid 的正方形的“行”和“列”,//然后将这两个数量相乘得到总的正方形数量,(只考虑完整的正方形)int res=(h[i]/mid)*(w[i]/mid);ans+=res;}return ans>=k;}
}

浮点二分

二分的二段性,集合中的元素有存在分界线,给定条件可以将集合中的元素分成两部分,一部分满足条件,一部分不满足

例题3 -浮点二分模板题

package com.study.erFen;import java.util.Scanner;//浮点二分
public class erFen1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int k = scan.nextInt();double[] a = new double[n];for(int i=0;i<n;i++)a[i]=scan.nextDouble();double left=0,right=1e9;while(right-left>1e-2) {double mid = (left+right)/2;if(check(a,mid,k))right=mid;else left=mid;}System.out.println(left);}public static boolean check(double[]a,double mid,double k) {int res=0;for(double x:a) {res+=(int)(x/mid);}return res<k;}
}

4.动态规划

例题1-程序员爬楼梯

package com.study.dp;import java.util.Scanner;public class dp1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//1.考虑最后一步由前面哪些状态转移来,推出转移方程//N可以由n-1 和n-3得来dp[i]=dp[i-1]+dp[i-3];//2.考虑当前状态与哪些状态有关 定义几维数组来表示当前状态//只和n有关 一维数组即可//3.计算时间复杂度 判断是否需要优化int n=scan.nextInt();if(n<3) {System.out.println(1);}else {int[] dp = new int[n+1];dp[1]=1;dp[2]=1;dp[3]=2;for(int i=4;i<=n;i++) dp[i]=dp[i-1]+dp[i-3];System.out.println(dp[n]);}}
}
例题2-最长上升子序列

package com.study.dp;import java.util.Scanner;public class dp2 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//以每个元素为结尾的最长上升子序列的长度作为状态//[1, 7, 3, 5, 9, 4, 8]//dp[0]=1 dp[1]=2(1-7) dp[2]=2(1-3) dp[3]=3(1-3-5) dp[4]=4(1-3-5-9)//对于每个i都需要查找前面比他小的元素j 然后找到最大的dp[j]+1作为dp[i]的值//为什么是dp[j]+1:找出的子序列还需要加上arr[i] (因为是严格满足arr[j]<arr[i]的)//由此可以得出 dp[i]=max(dp[j]+1)]int n = scan.nextInt();int[] arr = new int[n];for(int i=0;i<n;i++)arr[i]=scan.nextInt();int[] dp = new int[n];int maxLen=1;//最小为1dp[0]=1;for(int i=0;i<n;i++) {for(int j=0;j<i;j++) {if(arr[j]<arr[i]) {dp[i]=Math.max(dp[i], dp[j]+1);}}//每次循环结束更新一下maxLen的值maxLen=Math.max(maxLen, dp[i]);}System.out.println(maxLen);}
}
例题3-3512接龙数列*****
package com.study.dp;import java.util.Scanner;public class dp3 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//思路:找出最少删除多少个数使得剩下的数为接龙数列//找到状态的定义和转移  //dp数组记录以每个数字结尾的最长子序列长度 遍历每个数 计算其首尾数字更新对应的dp值//总长度-最长子序列长度即最少次数int n = scan.nextInt();int[] nums=new int[n];for(int i=0;i<n;i++)nums[i]=scan.nextInt();int[] dp = new int[10]; // dp[d] 表示以数字d结尾的最长接龙子序列的长度int maxLength = 0;for (int num : nums) {int h = getFirstDigit(num); // 当前元素的首位数字int t = Math.abs(num % 10);  // 当前元素的末位数字(处理负数情况)int maxPrev = 0;// 找出所有以h结尾的子序列中的最长长度for (int d = 0; d < 10; d++) {if (d == h) {maxPrev = Math.max(maxPrev, dp[d]);}}// 更新以t结尾的最长子序列长度dp[t] = Math.max(dp[t], maxPrev + 1);// 更新全局最长长度maxLength = Math.max(maxLength, dp[t]);}System.out.println(nums.length - maxLength);//在此输入您的代码...scan.close();}// 获取数字的首位数字(处理负数情况)private static int getFirstDigit(int num) {num = Math.abs(num);while (num >= 10) {num /= 10;}return num;}
}
例题4-4985蜗牛

5.最大公约数和最小公倍数(gcd,lcm)

例题1-信息与未来

package com.study.Math;import java.util.Scanner;public class math2 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int x = scan.nextInt();int y = scan.nextInt();int z = scan.nextInt();int d=gcd(x,y);d=gcd(d,z);System.out.println(d);}public static int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
}
例题2

package com.study.Math;import java.util.Arrays;
import java.util.Scanner;public class math1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n=scan.nextInt();int[] a=new int[n];for(int i=0;i<n;i++)a[i]=scan.nextInt();Arrays.sort(a);int d=a[1]-a[0];for(int i=2;i<n;i++)d=gcd(d,a[i]-a[i-1]);if(d==0){System.out.println(n);}else{long res=1;for(int i=1;i<n;i++){res+=(a[i]-a[i-1])/d;}System.out.println(res);}}public static int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
}

6.暴力搜索

package com.study.moni;import java.util.Scanner;
//n层就n层for循环 即暴力
public class Main5 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n=scan.nextInt();for(int i=1;i<=3;i++) {for(int j=1;j<=3;j++) {if(j==i) continue;for(int k=1;k<=3;k++) {if(k==i||k==j) continue;System.out.println(i+" "+j+" "+k);}}}}
}

7.进制转换

1.调用Integer.toString(x,y)方法,将x(十进制数)转换成y进制(字符串)

2.自己写

例题1

package com.study.Math;import java.util.Scanner;public class Math3 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int x = scan.nextInt();char[] c = scan.next().toCharArray();int sum=0,k=1;for(int i=c.length-1;i>=0;i--) {//逆序遍历 从最后一位开始处理int res=0;if(c[i]>='A'&&c[i]<='Z')//超过十进制res=c[i]-'A'+10;//表示是十几进制else res=c[i]-'0';//转换成对应的数字sum+=res*k;//当前位的数值*x^n次方 k*=x;//二进制转十进制如101=1*2^2+0*2^1+1*2^0//此处同理 }System.out.println(sum);}
}
例题2

package com.study.Math;import java.util.Scanner;public class math4 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int x = scan.nextInt();String str = Integer.toString(n,x).toUpperCase();System.out.println(str);}
}

8.常用api


 

9.DFS(深度优先搜索)

深度优先遍历(DFS)
核心思想:尽可能深地探索图的分支,直到没有未访问的相邻节点,再回溯继续探索其他分支。

  • 实现方式:用栈(或递归)保存待访问节点。
  • 特点:适合路径查找(如迷宫)、回溯问题,空间复杂度较低(仅需存储当前路径)。
  • 比喻:像“一条路走到黑”,深入到底再折返。

例题1-全排列

1<=n<=9

package com.study.DFS;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class dfs1 {static List<List<Integer>> list = new ArrayList<>();public static void main(String[] args) {Scanner scan = new Scanner(System.in);//为什么要用dfs:全排列需生成所有可能的元素排列组合,//DFS通过回溯法系统地探索所有决策路径,确保每个分支都被完整遍历。int n = scan.nextInt();//全排列的元素个数int[] v = new int[n+1];//标记是节点是否访问过List<Integer> t= new ArrayList<>();//集合dfs(n,v,t);//调用深度优先遍历算法for(int i=0;i<list.size();i++) {for(int j=0;j<list.get(i).size();j++) {System.out.print("     "+list.get(i).get(j));}System.out.println();}}public static void dfs(int n,int[]v,List<Integer>t) {//如果集合t的长度==排列数n 说明已经形成了完整的排列 将其添加到大集合中if(t.size()==n) {list.add(new ArrayList<>(t));return ;//递归出口}//否则遍历所有可能的数字(1-n)//如果i没有被标记为已使用(v[i]==0),//就标记它为已使用,添加到当前排列t中,然后递归调用dfsfor(int i=1;i<=n;i++) {if(v[i]==1)continue;v[i]=1;t.add(i);//标记该路径已尝试dfs(n,v,t);v[i]=0;//将当前选择的数字标记为"未使用",允许上层递归重新选择该数字t.remove(t.size()-1);//从当前路径中移除最后添加的数字,使路径回退到上一层状态/** 想象你在迷宫中探索:v[i]=1 + t.add(i):你走进一条死胡同,标记该路径为已尝试。v[i]=0 + t.remove():发现死胡同后原路返回,清除标记,尝试其他岔路。*/}}
}
图的搜索

例题1-264危险系数

package com.study.DFS;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class dfs2 {//站点即节点数量 通道数即边数量//m行是初始化边 如 1-3 2-3 3-4 3-5 4-5 5-6static List<Integer>[] list;//list是一个数组的列表,用于存储每个节点的邻接节点。static boolean[] visited; // 数组标记访问状态static boolean flag = false;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();list = new List[n + 1];// 为每个节点初始化一个空的邻接列表//每个节点的邻接列表是邻接表的一部分,而不是独立的邻接表。for (int i = 1; i <= n; i++) {list[i] = new ArrayList<>();}//无向图 初始化邻接表//遍历所有的边,将邻接节点添加到相应的列表中for (int i = 0; i < m; i++) {int x = scan.nextInt();int y = scan.nextInt();list[x].add(y);// 将 y 添加到 x 的邻接列表中list[y].add(x);// 将 x 添加到 y 的邻接列表中}int x = scan.nextInt();int y = scan.nextInt();visited = new boolean[n + 1]; // 初始化访问数组// 初始连通性检查flag = false;dfs(x, y, x, 0);//x y是否连通if (!flag) {System.out.println(-1);} else {int ans = 0;for (int i = 1; i <= n; i++) {//遍历所有节点 跳过x y 孤立点if (i == x || i == y || list[i].isEmpty()) continue;// 每次测试前重置访问标记 for (int j = 1; j <= n; j++) visited[j] = false;flag = false;dfs(x, y, x, i);//传入i作为blockif (!flag) ans++;//若移除 i 后 x 和 y 不连通,危险系数ans 加一}System.out.println(ans);}}/*** 递归的搜索是否存在从起点到终点的路径 同时排除被屏蔽的节点* @param s 起点* @param t 终点* @param u 当前节点* @param block 需要屏蔽的节点*/public static void dfs(int s, int t, int u, int block) {if (u == t) {flag = true;return;//递归出口 已经找到终点}visited[u] = true; // 标记当前节点已访问for (int v : list[u]) {//遍历当前节点的邻接节点if (!visited[v] && v != block) { // 未被访问过且遍历的邻接节点不是阻塞的节点dfs(s, t, v, block);//递归调用dfs以v为当前节点 继续搜索路径if (flag) return; // 找到后立即终止递归}}}
}
剪枝

例题

package com.study.dp;import java.util.Scanner;public class dp4 {static int n,k,ans=0;public static void main(String[] args) {Scanner scan = new Scanner(System.in);n=scan.nextInt();//数Nk=scan.nextInt();//要分K份dfs(1,0,0);System.out.println(ans);}/*** * @param last 上一份的值* @param sum 当前已分出的总和* @param cnt 已分的份数*/public static void dfs(int last,int sum,int cnt) {if(cnt==k) {if(sum==n) {//已分份数和已分总和等于k,n 计数器++ans++;}return;//递归终止条件}//未剪枝写法
//		for(int i=last;i<=n;i++) {
//			dfs(i,sum+i,cnt+1);
//		}//从last开始递增 确保大于上一份的值//剪枝条件 未分配的数 (sum-n)至少能分成k-cnt份 每份至少大于ifor(int i=last;sum+i*(k-cnt)<=n;i++) {//剪枝循环dfs(i,sum+i,cnt+1);}}
}

10.BFS(广度优先搜索)

广度优先搜索(BFS)是一种用于遍历或搜索树或图的算法。它的核心思想是从根节点开始,逐层访问邻近的节点,直到找到目标节点或遍历完所有节点。

通过队列实现,队列(先进先出)

例题

package com.study.BFS;import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;public class bfs1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();char[][]c=new char[n][m];for(int i=0;i<n;i++)c[i]=scan.next().toCharArray();//一列一列的读int ans=0;for(int i=0;i<n;i++) {//遍历每个网格for(int j=0;j<m;j++) {if(c[i][j]!='0') {//是细胞就BFS一下bfs(i,j,c);ans++;}}}System.out.println(ans);}public static void bfs(int i,int j,char[][]c) {int n=c.length;//行数int m=c[0].length;//列数Queue<int[]>q=new LinkedList<>();//创建队列q.add(new int[] {i,j});//将初始坐标加入队列中int[][]dx= {{1,0},{-1,0},{0,1},{0,-1}};//定义方向数组while(!q.isEmpty()) {//终止条件:队列不为空int[]a=q.poll();//获取队列中第一个元素int x=a[0];//获得x坐标int y=a[1];//获得y坐标c[x][y]='0';//将当前节点设为已访问for(int k=0;k<4;k++) {//遍历四个方向,计算相邻节点的坐标x1和y1int x1=x+dx[k][0];int y1=y+dx[k][1];if(x1<0||x1>=n||y1<0||y1>=m||c[x1][y1]=='0')//未越界且未被访问continue;q.add(new int[] {x1,y1});//将合法未访问节点加入队列}}}
}

刷题记录

1.504-单词分析***

模拟/枚举
package com.study.BL;import java.util.Scanner;//暴力
public class bl1 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//思路1:双重for暴力求解 只能通过70%的测试点/**char[] c = scan.next().toCharArray();char result=' ';int maxLen=0;for(int i=0;i<c.length;i++) {int max=0;char currentChar=c[i];for(int j=0;j<c.length;j++) {if(currentChar==c[j]) {max++;}}if(maxLen<max) {maxLen=max;result=currentChar;}}System.out.println(result);System.out.println(maxLen);*///思路2 利用数组来记录长度char[] c = scan.next().toCharArray();int[] counts = new int[26];for(char a:c) {counts[a-'a']++;}//一层循环找出数组中最大的值int max=0;char result=' ';for(int i=0;i<26;i++) {if(counts[i]>max) {max=counts[i];result = (char) ('a' + i);}}System.out.println(result);System.out.println(max);scan.close();}
}

2.19709-好数**

暴力/枚举/位处理
public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...int num = scan.nextInt();int ans=0;for(int i=1;i<=num;i++) {ans+=method(i);}System.out.println(ans);scan.close();}public static int method(int n) {int count=0;int a=1;//记录当前是那位 首先是个位boolean flag=true;while(n!=0) {//对于个位数只用判断奇数位 但多位数需要每个位数都满足//正难则反去不满足的int t = n%10;//取出当前n的个位if(a%2==1){//奇数位if(t%2==0)flag=false;}else{//偶数位if(t%2==1)flag=false;}a++;n/=10;}if(flag) {return 1;}else {return 0;}}

3.1216-走迷宫***

bfs
package com.study.BFS;import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;public class bfs2 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//思路:采用二维数组来记录步数 和迷宫同样大小 但含义是到达该格子的步数int n = scan.nextInt();int m = scan.nextInt();int[][] grid = new int[n][m];for(int i=0;i<n;i++) {for(int j=0;j<m;j++) {grid[i][j]=scan.nextInt();}}//读取出入口坐标 并转成0索引开头int x1 = scan.nextInt()-1;int y1 = scan.nextInt()-1;int x2 = scan.nextInt()-1;int y2 = scan.nextInt()-1;int[][]steps = new int[n][m];for(int[] a:steps) {Arrays.fill(a, -1);//初始化位-1 表示未访问}//创建队列Queue<int[]> q = new LinkedList<>();q.add(new int[]{x1,y1});//起点入队steps[x1][y1]=0;//起点步数为0int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};while(!q.isEmpty()) {int[] current = q.poll();int x = current[0];int y = current[1];//循环终止条件:找到出口后返回步数if(x==x2&&y==y2) {System.out.println(steps[x][y]);return;}//探索四个方向for(int[]dir:dirs) {int nx = x+dir[0];int ny = y+dir[1];//检查新坐标是否合法且未被访问if(nx>=0&&ny>=0&&nx<n&&ny<m&&grid[nx][ny]==1&&steps[nx][ny]==-1) {steps[nx][ny]=steps[x][y]+1;//更新步数q.add(new int[] {nx,ny}	);}}}System.out.println(-1);}
}

4.3447-七步诗***

dfs/bfs
package com.study.BFS;import java.util.Arrays;
import java.util.Scanner;public class bfs3 {static boolean visited[][];static int sum;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();char[][] c = new char[n][m];for(int i=0;i<n;i++) {c[i]=scan.next().toCharArray();}visited=new boolean[n][m];for(int i=0;i<n;i++) {Arrays.fill(visited[i], false);}sum=0;//遍历二维字符数组for(int i=0;i<n;i++) {for(int j=0;j<m;j++) {if(c[i][j]=='S'&&!visited[i][j]) {dfs(i,j,c);}}}System.out.println(sum);}public static void dfs(int x,int y,char[][] c) {//定义二维数组 记录马儿飞的八个方向int[][] jump = {{2,-1},{2,1},{1,-2},{1,2},{-1,2},{-1,-2},{-2,-1},{-2,1}};//数据不能越界int n = visited.length;int m = visited[0].length;if(x<0||y<0||x>=n||y>=m)return;visited[x][y]=true;//标记为已访问if(c[x][y]=='b') {sum++;}//循环可以走的所有点 切判断点是否合法 且不能等于xfor(int i=0;i<8;i++) {int nx = x+jump[i][0];int ny = y+jump[i][1];if(nx>=0&&ny>=0&&nx<n&&ny<m&&c[nx][ny]!='x'&&!visited[nx][ny]) {//未越界 未被访问 不是湿地//判断下一个点是否满足dfs(nx,ny,c);}}}
}
package com.study.BFS;import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;public class bfs3 {static boolean visited[][];static int sum;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();char[][] c = new char[n][m];for(int i=0;i<n;i++) {c[i]=scan.next().toCharArray();}visited=new boolean[n][m];for(int i=0;i<n;i++) {Arrays.fill(visited[i], false);}sum=0;//使用队列进行bfs遍历Queue<int[]> q = new LinkedList<>();//找到起点并加入队列for(int i=0;i<n;i++) {for(int j=0;j<m;j++) {if(c[i][j]=='S') {q.add(new int[] {i,j});visited[i][j]=true;//找到起点后立刻退出循环break;}}}//移动的8个方向int[][] jump = {{2,-1},{2,1},{1,-2},{1,2},{-1,2},{-1,-2},{-2,-1},{-2,1}};//bfswhile(!q.isEmpty()) {int[] current = q.poll();//取出来int x = current[0];int y = current[1];if(c[x][y]=='b') {sum++;}for(int[] dir:jump) {int nx = x+dir[0];int ny = y+dir[1];//检查新位置是否合法等if(nx>=0&&nx<n&&ny>=0&&ny<m&&c[nx][ny]!='x'&&!visited[nx][ny]) {visited[nx][ny]=true;q.add(new int[] {nx,ny});//放入}}}System.out.println(sum);}
}

5.502-成绩统计*

数学
package com.study.Math;import java.util.Scanner;public class math5 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//调用Math.round方法进行四舍五入int n = scan.nextInt();int a=0,b=0;//优秀 及格int c;for(int i=1;i<=n;i++) {c=scan.nextInt();if(c>=60)a++;if(c>=85)b++;}double passRate = (double)a/n*100;double excellentRate = (double)b/n*100;int pr = (int)Math.round(passRate);int er = (int)Math.round(excellentRate);System.out.println(pr+"%");System.out.println(er+"%");scan.close();}
}

6.498-回文日期(90)****

模拟 构造 回文

防超时

优化点说明:

  1. 分离循环: 为两种日期类型分别设置循环,找到结果后立即终止。
  2. 减少字符串转换: 在生成日期时直接操作字符串,避免重复转换。
  3. 提前终止: 找到符合条件的日期后立即返回,减少不必要的循环。
package com.study.moni;import java.util.Scanner;public class Main6 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();// 寻找下一个回文日期for (int i = n + 1; i < 89991231; i++) {if (isLegalDate(i) && isHW(i)) {System.out.println(i);break;}}// 寻找下一个ABABBABA日期for (int i = n + 1; i < 89991231; i++) {if (isLegalDate(i) && isAB(i)) {System.out.println(i);break;}}scan.close();}public static boolean isHW(int n) {char[] c = Integer.toString(n).toCharArray();int left = 0, right = 7;while (left < 4) {if (c[left] != c[right]) return false;left++;right--;}return true;}public static boolean isAB(int n) {char[] c = Integer.toString(n).toCharArray();return c[0] == c[2] && c[0] == c[5] && c[0] == c[7] &&c[1] == c[3] && c[1] == c[4] && c[1] == c[6];}public static boolean isLegalDate(int n) {if(n<10000101||n>89991231)return false;String s = Integer.toString(n);int year = Integer.parseInt(s.substring(0, 4));int month = Integer.parseInt(s.substring(4, 6));int day = Integer.parseInt(s.substring(6, 8));if (month < 1 || month > 12) return false;int[] maxDays = {31,28,31,30,31,30,31,31,30,31,30,31};if (day < 1 || day > maxDays[month-1]) return false;return true;}
}

7.101拉马车***

模拟 字符串操作
package com.study.moni;import java.util.Scanner;public class Main7 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//题意:输入两副牌 直到有一方没牌可出游戏结束//出牌规则:从自己的纸牌队列的头部拿走一张,放到桌上,并且压在最上面一张纸牌上(如果有的话)//赢牌条件:所出牌k和牌桌上有K ,赢牌的一方继续出牌,可赢走包括包括//K在内的以及两k之间的纸牌都赢回来,放入自己牌的队尾(注意是翻转后拼接 需要用到reverse()方法)//注意:为了操作方便,放入牌的顺序是与桌上的顺序相反的。也就是说放入桌上的牌是可以直接通过append方法拼接的//思路:通过StringBuilder对字符串进行一系列操作//主要用到的方法 StringBuilder的append用来拼接到字符串末尾  //String.charAt(i)取走第i个元素//sb.indexOf:返回指定字符串第一次出现在字符串中的索引 若没有则返回-1或自己设置的默认值//sb.subString(index)截取该下标后的字符串//String.vauleOf()将()转为字符串StringBuilder a = new StringBuilder(scan.next());StringBuilder b = new StringBuilder(scan.next());//牌桌StringBuilder desk = new StringBuilder();boolean flag = true;//控制AB出牌 trueA出牌 falseb出牌while(a.length()>0&&b.length()>0) {char currentCard;//出的牌StringBuilder currentHand;//当前是谁的手牌if (flag) {if (a.length() == 0) break;currentCard = a.charAt(0);currentHand = a;} else {if (b.length() == 0) break;currentCard = b.charAt(0);currentHand = b;}// 先出牌到桌面desk.append(currentCard);currentHand.delete(0, 1);//检查赢牌条件//indexOf从位置0开始查找当前牌在桌面字符串中的位置int index = desk.indexOf(String.valueOf(currentCard));//判断的是当前牌是否是桌面上的唯一存在 desk.length() - 1是刚刚放入的if (index!= desk.length() - 1) {//索引位置不等于刚刚放入牌的索引位置 则说明有这个牌了已经//计算赢牌范围StringBuilder won = new StringBuilder(desk.substring(index));won.reverse();currentHand.append(won);desk.delete(index , desk.length());continue; // 继续由当前玩家出牌}// 切换玩家flag = !flag;}System.out.println(a.length()==0?b:a);scan.close();}
}

8.126交换瓶子*

模拟
public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...int n = scan.nextInt();int[] arr = new int[n+1];for(int i=1;i<=n;i++) {arr[i]=scan.nextInt();}int count=0;//编号不为i的就进行交换for(int i=1;i<=n;i++) {if(arr[i]!=i) {int j=1;for(j=i;j<=n;j++) {if(arr[j]==i) {//找到了编号i对应的数 把这个数和i交换break;}}int temp = arr[i];arr[i]=i;arr[j]=temp;count++;}}System.out.println(count);scan.close();}

9.130-移动距离***

bfs寻找最短路径
package com.study.moni;import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;public class Main9 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);// 读取输入int w = scan.nextInt();int m = scan.nextInt();int n = scan.nextInt();//思路:通过bfs来寻找最短路径 先要获取起点和终点坐标int[] start = getZuoBiao(m,w);int[] end = getZuoBiao(n,w);//bfs初始化int[][]dirs = {{1,0},{-1,0},{0,1},{0,-1}};boolean[][] visited = new boolean[10000][w];Queue<int[]> q = new LinkedList<>();//传入三个参数 坐标和移动距离//传入起点visited[start[0]][start[1]]=true;q.add(new int[] {start[0],start[1],0});//bfswhile(!q.isEmpty()) {int[] current = q.poll();int x = current[0];int y = current[1];int dis = current[2];//四个方向进行遍历for(int[]dir:dirs) {int nx = x+dir[0];int ny = y+dir[1];//检查新坐标是否合法if (nx >= 0 && ny >= 0 && nx < 10000 && ny < w && !visited[nx][ny]) {//找到终点结束循环if(nx==end[0]&&ny==end[1]) {System.out.println(dis+1);scan.close();return;}//未到终点更新状态继续找q.add(new int[] {nx,ny,dis+1});visited[nx][ny]=true;}}}}public static int[] getZuoBiao(int n,int width) {//计算在第几行 索引从0开始int row = (n-1)/width;//计算行内位置 余数即从左或从右的第几个数012...int r = (n-1)%width;int c;if(row%2==0) {//奇数行 正序c=r;}else {//偶数行 逆序 如左边第2个数 实际上是右边第width-r-1个数123456c=width-r-1;}return new int[] {row,c};}
}

10.145数位递增的数*

模拟 位分离
package com.study.moni;import java.util.Scanner;public class Main10 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...int n =scan.nextInt();int count=0;for(int i=1;i<=n;i++){if(isDZ(i)){count++;
//	                System.out.println(i);}}System.out.println(count);scan.close();}public static boolean isDZ(int n){if(n<10) {return true;}int temp=0;//记录上一次的位数字while(n!=0){//12int t = n%10;//2if((t>temp&&temp!=0)||t==0){//到个位不比较return false;}temp = t;//temp=2n/=10;//1}return true;}
}

11.146三元数组中心问题**

暴力
package com.study.BL;import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;public class bl3 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//直接暴力 无需多言int n = scan.nextInt();int[] arr = new int[n];for(int i=0;i<n;i++){arr[i]=scan.nextInt();}//利用set集合来存储符合条件的j(中心)防止重复Set<Integer> s = new HashSet<>();for(int i=0;i<n-2;i++){//-2是预留jkfor(int j=i+1;j<n-1;j++){if(arr[j]>arr[i]){//满足左边才继续循环for(int k=j+1;k<n;k++){if(arr[k]>arr[j]){s.add(j);break;//找到了立即结束循环 优化性能}}}}}System.out.println(s.size());scan.close();}
}

12.148音节判断

模拟
public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//顺序:辅元辅元 //满足上述条件 从1(索引)开始判断 辅音跳过 char[] a = scan.next().toCharArray();//利用两个Boolean类型的值来控制判断是元音还是辅音boolean f1 = true,f2 = true;int m=0;//记录符合条件的次数for(int i=0;i<a.length;i++) {if((a[i]!='a' && a[i]!='e' && a[i]!='i' && a[i]!='o' && a[i]!='u')&&f1) {m++;f1=false;f2=true;}if((a[i] == 'a' || a[i] == 'e' || a[i] == 'i' || a[i] == 'o' || a[i] == 'u') && f2) {m++;f2 = false;f1=true;}}System.out.println(m==4?"yes":"no");scan.close();}

13.149-长草***

bfs
package com.study.BFS;import java.util.*;public class bfs4 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();char[][] grid = new char[n][m];for(int i=0; i<n; i++) {grid[i] = scan.next().toCharArray();}int k = scan.nextInt();int[][] dirs = {{1,0}, {-1,0}, {0,1}, {0,-1}};for(int steps = 0; steps < k; steps++) {boolean[][] visited = new boolean[n][m];Queue<int[]> queue = new LinkedList<>();// 每月先收集当前所有草地位置for(int i=0; i<n; i++) {for(int j=0; j<m; j++) {if(grid[i][j] == 'g' && !visited[i][j]) {queue.add(new int[]{i, j});visited[i][j] = true;}}}// 执行BFS扩散while(!queue.isEmpty()) {int[] current = queue.poll();for(int[] dir : dirs) {int nx = current[0] + dir[0];int ny = current[1] + dir[1];if(nx >=0 && ny >=0 && nx < n && ny < m && !visited[nx][ny] && grid[nx][ny] != 'g') {grid[nx][ny] = 'g';visited[nx][ny] = true;//关键点就是每月只对g点进行一轮扩散 所以此处不需要再从新添加队列了
//                        queue.add(new int[]{nx, ny});}}}}// 输出结果for(int i=0; i<n; i++) {System.out.println(new String(grid[i]));}scan.close();}
}

14.1065寻找2020**

模拟
package com.study.BL;import java.util.Scanner;public class bl4 {static int count=0;public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...直接暴力试一试 虽然多 但行列应该不超过500char[][] c = new char[300][300];for(int i=0;i<c.length;i++) {c[i]=scan.next().toCharArray();}for(int i=0;i<c.length;i++) {for(int j=0;j<c.length;j++) {is2020(i,j,c);}}System.out.println(count);}//进行判断public static void is2020(int i,int j,char[][]c) {if(i+3<c.length) {StringBuilder sb = new StringBuilder();sb.append(c[i][j]);sb.append(c[i+1][j]);sb.append(c[i+2][j]);sb.append(c[i+3][j]);if(sb.toString().equals("2020")) {count++;}}if(j+3<c.length) {StringBuilder sb = new StringBuilder();sb.append(c[i][j]);sb.append(c[i][j+1]);sb.append(c[i][j+2]);sb.append(c[i][j+3]);if(sb.toString().equals("2020")) {count++;}}if(j+3<c.length&&i+3<c.length) {StringBuilder sb = new StringBuilder();sb.append(c[i][j]);sb.append(c[i+1][j+1]);sb.append(c[i+2][j+2]);sb.append(c[i+3][j+3]);if(sb.toString().equals("2020")) {count++;}}}
}

15.19699类斐波那契循环数

暴力 构造 枚举
package com.study.BFS;public class bfs5 {public static void main(String[] args) {//在此输入您的代码...//猜测最大的类斐波那契数在1000000-9999999之间for(int i=9999999;i>=5000000;i--){if(isFeiBo(i)){System.out.println(i);break;}}}public static boolean isFeiBo(int n){//利用数组来存储数列 前七位是该数的每一位//后面要对n进行处理 先记录n的值int m =n;int[] a = new int[50];for(int i=6;i>=0;i--){a[i]=n%10;n/=10;}int k=0;int sum=0;//超过n后还没有值等于n说明不是类斐波那契数//a8=a1+...+a7 防止数组越界while(sum<m&&k+7<50){a[k+7]=a[k]+a[k+1]+a[k+2]+a[k+3]+a[k+4]+a[k+5]+a[k+6];sum=a[k+7];k++;if(sum==m){return true;}} return false;}
}

16.19732分布式队列

模拟
public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//本题并没有涉及到打印队列中的元素 只涉及到个数可用一个n大小的数组来记录个数int n = scan.nextInt();int[] count = new int[n];while(scan.hasNext()) {String s = scan.next();if(s.equals("add")) {//添加操作int x = scan.nextInt();count[0]++;//主节点}else if(s.equals("sync")) {//同步操作 元素添加到主节点后,需要同步到所有的副节点后int x = scan.nextInt();//副节点会从主节点中同步下一个自己缺失的元素
//        		count[x]++;同步一次 该队列的元素个数+1,但不可能超过主节点的元素数count[x]=Math.min(count[x]+1,count[0]);}else {//查询操作//查看分布式队列中有多少个元素可见 //所有节点都有这个元素这个元素才算可见 故即找出队列数组中的最小值int min = count[0];for(int i=1;i<n;i++) {if(count[i]<min) {min=count[i];}}System.out.println(min);}}scan.close();}

17.19724食堂

贪心

贪心的核心优先级:

  1. 满桌优先 首先一定是让桌子都塞满人,这样利用率才能最大化。
  2. 小桌优先 先把人放到小桌中,因为小桌(4人桌)的人数组合搭配不够灵活,大桌(6人桌)可以有更多中组合搭配。
  3. 人多优先 寝室人多的先安置,因为人多不灵活,如果后面不能安置了,那么会损失很多人,利用率就下降了。
  4. 空少优先 当一个桌子不得不空出位置时,尽量少空出位置。(空出位置数相同时,优先排6人桌的,因为人相对于排4人桌更多)
public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//要尽可能空桌少int q = scan.nextInt();while(q!=0){q--;int a2 = scan.nextInt();int a3 = scan.nextInt();int a4 = scan.nextInt();int b4 = scan.nextInt();int b6 = scan.nextInt();//四人寝四人坐int sum=0;//满座匹配4人寝坐4人桌while(b4>0&&a4>=1) {b4--;a4--;sum+=4;}//满座匹配2x2人寝坐4人桌while(b4>0&&a2>=2) {b4--;a2-=2;sum+=4;}//满座匹配2+4人寝坐6人桌while(b6>0&&a4>=1&&a2>=1) {b6--;a4--;a2--;sum+=6;}//满座匹配2x3人寝坐6人桌while(b6>0&&a3>=2) {b6--;a3-=2;sum+=6;}//满座匹配3x2人寝坐6人桌while(b6>0&&a2>=3) {b6--;a2-=3;sum+=6;}//空1座匹配2+3人寝坐6人桌while(b6>0&&a2>=1&&a3>=1) {b6--;a2--;a3--;sum+=5;}//空1座匹配3人寝坐4人桌while(b4>0&&a3>0) {b4--;a3--;sum+=3;}//空2座匹配2x2人寝坐6人桌while(b6>0&&a2>=2) {b6--;a2-=2;sum+=4;}//空2座匹配4人寝坐6人桌while(b6>0&&a4>0) {b6--;a4--;sum+=4;}//空2座匹配2人寝坐4人桌while(b4>0&&a2>0) {b4--;a2--;sum+=2;}//空3座匹配3人寝坐6人桌while(b6>0&&a3>0) {b6--;a3--;sum+=3;}//空4座匹配2人寝坐6人桌while(b6>0&&a2>0) {b6--;a2--;sum+=2;}System.out.println(sum);}scan.close();}

相关文章:

蓝桥杯备考

先浅学一遍数据结构&#xff0c;不会拉倒&#xff0c;找点简单题练练语法基础 然后边学边刷二分查找和双指针 递归和暴力&#xff0c;边学边刷 学习贪心&#xff0c;练个几十道 再去过下数据结构 开始算法:搜索&#xff0c;动态规划&#xff0c; 搜索很重要&#xff0c;深…...

Elasticsearch 系列专题 - 第一篇:Elasticsearch 入门

Elasticsearch 是一个功能强大的开源分布式搜索和分析引擎,广泛应用于日志分析、实时搜索、数据可视化等领域。本篇将带你了解 Elasticsearch 的基本概念、安装方法以及简单操作,帮助你快速上手。 1. 什么是 Elasticsearch? 1.1 Elasticsearch 的定义与核心概念 Elasticse…...

【LeetCode 题解】数据库:1321.餐馆营业额变化增长

一、问题描述 本题给定了一个名为 Customer 的表&#xff0c;记录了餐馆顾客的交易数据&#xff0c;包括顾客 ID、姓名、访问日期和消费金额。作为餐馆老板&#xff0c;我们的任务是分析营业额的变化增长情况&#xff0c;具体来说&#xff0c;就是计算以 7 天&#xff08;某日…...

Apache Nifi安装与尝试

Apache NIFI中文文档 地址&#xff1a;https://nifichina.github.io/ 下载安装配置 1、环境准备 Nifi的运行需要依赖于java环境&#xff0c;所以本机上需要安装java环境&#xff0c;并配置环境变量。 1.1查看本机是否已经存在java环境 请先执行以下命令找出系统中真实可用…...

【Git 常用操作指令指南】

一、初始化与配置 1. 设置全局账户信息 git config --global user.name "用户名" # 设置全局用户名 git config --global user.email "邮箱" # 设置全局邮箱 --global 表示全局生效&#xff0c;若需针对单个仓库配置&#xff0c;可省略该参数 2.…...

Django 生成PDF文件

在这里&#xff0c;我们将学习如何使用Django视图设计和生成PDF文件。我们将使用ReportLab Python PDF库生成PDF&#xff0c;该库可以创建定制的动态PDF文件。 这是一个开源库&#xff0c;可以通过在Ubuntu中使用以下命令轻松下载。 $ pip install reportlab Python Copy …...

多账户使用Github的场景,设置 SSH 多账号使用特定 key

遇到多账户使用Github的场景&#xff0c;常难以管理ssh文件 解决方案&#xff1a; 你可以通过配置 ~/.ssh/config 文件&#xff0c;生成多个SSH key 让 Git 识别不同 key 来对应不同 GitHub 账号。 ✅ 正确的 key 类型有这些常见选项&#xff1a; rsa&#xff1a;老牌算法&a…...

js中this指向问题

在js中&#xff0c;this关键字的指向是一个比较重要的概念&#xff0c;它的值取决于函数的调用方式。 全局状态下 //全局状态下 this指向windowsconsole.log("this", this);console.log("thiswindows", this window); 在函数中 // 在函数中 this指向win…...

BabelDOC ,开源的 AI PDF 翻译工具

BabelDOC 是一款开源智能 PDF 翻译工具&#xff0c;专门为科学论文的翻译而设计。它能够在原文旁边生成翻译文本&#xff0c;实现双语对照&#xff0c;用户无需频繁切换窗口&#xff0c;极大提升了阅读的便利性。此外&#xff0c;BabelDOC 能够完整保留数学公式、表格和图形&am…...

Dify 生成提示词的 Prompt

Dify 生成提示词的 Prompt **第1次提示词****第2次提示词****第3次提示词**总结 Dify 生成提示词是&#xff0c;会和LLM进行3次交互&#xff0c;下面是和LLM进行交互是的Prompt。 以下是每次提示词的概要、目标总结以及原始Prompt&#xff1a; 第1次提示词 概要&#xff1a; …...

在nvim的snippet补全片段中增加函数注释的功能

一、补全片段路径 如果使用nvim,应当在nvim的snippet的插件中增加对应补全的片段&#xff0c;目前我所用的补全的片段路径如下&#xff1a; /home/zhaoky/.local/share/nvim/site/pack/packer/start/vim-snippets.git/snippets我当前补全的是c语言所以使用的片段是c.snippets…...

阿里云负载均衡为何费用高昂?——深度解析技术架构与市场定价策略

本文深度解析阿里云负载均衡&#xff08;SLB&#xff09;产品的定价体系&#xff0c;从技术架构、安全防护、合规成本三个维度揭示费用构成逻辑。通过2023年某跨国企业遭受的混合型DDoS攻击案例&#xff0c;结合Gartner最新安全支出报告&#xff0c;给出企业级负载均衡成本优化…...

大数据(7)Kafka核心原理揭秘:从入门到企业级实战应用

目录 一、大数据时代的技术革命1.1 消息中间件演进史1.2 Kafka核心设计哲学 二、架构深度解构2.1 核心组件拓扑2.1.1 副本同步机制&#xff08;ISR&#xff09; 2.2 生产者黑科技2.3 消费者演进路线 三、企业级应用实战3.1 金融行业实时风控3.2 物联网数据管道 四、生产环境优化…...

01背包 Java

① 记忆化搜索解法&#xff1a; import java.util.*; import java.io.*;public class Main {static int n, m;static int[] v, w;static int[][] memory; // 记忆化数组public static void main(String[] args) throws Exception {BufferedReader br new BufferedReader(new …...

【Kafka基础】消费者命令行完全指南:从基础到高级消费

Kafka消费者是消息系统的关键组成部分&#xff0c;掌握/export/home/kafka_zk/kafka_2.13-2.7.1/bin/kafka-console-consumer.sh工具的使用对于调试、测试和监控都至关重要。本文将全面介绍该工具的各种用法&#xff0c;帮助您高效地从Kafka消费消息。 1 基础消费模式 1.1 从最…...

Seq2Seq - 编码器(Encoder)和解码器(Decoder)

本节实现一个简单的 Seq2Seq&#xff08;Sequence to Sequence&#xff09;模型 的编码器&#xff08;Encoder&#xff09;和解码器&#xff08;Decoder&#xff09;部分。 重点把握Seq2Seq 模型的整体工作流程 理解编码器&#xff08;Encoder&#xff09;和解码器&#xff08…...

@SchedulerLock 防止分布式环境下定时任务并发执行

背景 在一个有多个服务实例的分布式系统中&#xff0c;如果你用 Scheduled 来定义定时任务&#xff0c;所有实例都会执行这个任务。ShedLock 的目标是只让一个实例在某一时刻执行这个定时任务。 使用步骤 引入依赖 当前以redisTemplate为例子&#xff0c;MongoDB、Zookeeper…...

【力扣hot100题】(077)跳跃游戏

我最开始的想法还是太单纯了&#xff0c;最开始想着用回溯法&#xff0c;然后想到上一题的经验又想到了动态规划&#xff0c;虽然知道贪心题不太可能会这么复杂但实在想不出别的办法……果然我的智商做贪心题的极限就只能达到找零问题那种水平…… 最开始的方法&#xff0c;击…...

多光谱相机:林业监测应用(病虫害、外来物种、森林防火识别)

随着气候变暖和人类活动的增加&#xff0c;森林火灾发生的频率和强度都有所上升&#xff0c;而我国森林防火基础设施薄弱&#xff0c;监测预警体系不够完善&#xff0c;扑救能力和应急响应能力有待提高。气候变化导致气温升高、降水分布不均等&#xff0c;影响了树木的生长和发…...

Dynamic Programming(LeetCode 740)

740. 删除并获得点数 相关企业提示给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。 每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除 所有 等于 nums[i] - 1 和 nums[i] 1 的元素。 开始你…...

虚拟列表react-virtualized使用(npm install react-virtualized)

1. 虚拟化列表 (List) // 1. 虚拟化列表 (List)import { List } from react-virtualized; import react-virtualized/styles.css; // 只导入一次样式// 示例数据 const list Array(1000).fill().map((_, index) > ({id: index,name: Item ${index},description: This is i…...

[特殊字符] 手机连接车机热点并使用 `iperf3` 测试网络性能

好的&#xff0c;以下是根据你的描述整理出来的步骤及解释&#xff1a; &#x1f4f6; 手机连接车机热点并使用 iperf3 测试网络性能 本文将通过 iperf3 来测试手机和车机之间的网络连接性能。我们会让车机作为服务端&#xff0c;手机作为客户端&#xff0c;进行 UDP 流量传输…...

C#,VB.NET正则表达式法替换代码

如何设置必须是MGBOX开头, msgbox这种注释自动跳过 在 Visual Studio 中使用 Ctrl H 进行替换操作时&#xff0c;若要确保仅替换以 MsgBox 开头的代码&#xff0c;同时跳过注释里的 MsgBox&#xff0c;可以利用正则表达式来实现。以下为你详细介绍操作步骤&#xff1a; 1. 打…...

从MySQL快速上手大数据Hive

从MySQL快速上手大数据Hive Hive简介 ​ hive是基于Hadoop构建的一套数据仓库分析系统&#xff0c;它提供了丰富的SQL查询方式&#xff08;DML&#xff09;来分析存储在Hadoop分布式文件系统中的数据: 可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供完整的SQL查…...

基于华为云kubernetes的应用多活的示例

1 概述 为避免地域级别的故障&#xff0c;需要将单机房架构变成双地域架构&#xff08;两个机房物理距离越远&#xff0c;网络延时越大&#xff0c;网延时是业务研发首先关注的&#xff09;。单边写的多机房架构&#xff0c;是落地性比较大的一个方案&#xff0c;相对于单元化…...

Linux动态库 vs 静态库:创建步骤与优缺点对比

Linux系列 文章目录 Linux系列前言一、动静态库的概念引入1.1 库的基本概念1.2 静态库&#xff08;Static Library&#xff09;1.3 动态库&#xff08;Dynamic Library&#xff09;1.4 动静态库的核心区别 二、动静态库的实现2.1 静态库的创建及使用2.2 动态库的创建和使用三、…...

分析下HashMap容量和负载系数,它是怎么扩容的?

很好&#xff0c;我们继续深入分析 HashMap 中 容量&#xff08;capacity&#xff09; 和 负载因子&#xff08;load factor&#xff09;&#xff0c;以及它是如何进行 扩容&#xff08;resize&#xff09; 的。 &#x1f9f1; 一、容量&#xff08;capacity&#xff09;与负载…...

Linux权限管理:从入门到实践

目录 引言 ​编辑一、Linux用户类型 二、文件访问者分类 三、文件类型和访问权限 &#xff08;一&#xff09;文件类型 &#xff08;二&#xff09;基本权限 四、文件访问权限设置方法 &#xff08;一&#xff09;chmod命令 &#xff08;二&#xff09;chown命令 &…...

计算机网络(1)

名称解析 名称解析&#xff1a;将名称解析成对应地址&#xff0c;名字-->IP 名称解析优点&#xff1a;便以记忆、解耦&#xff08;断开直接的练习&#xff09; 容器 mini的虚拟机&#xff0c;该容器地址是动态的、生命周期短暂&#xff1b;可实现登录功能 如果用户想要登录该…...

第十一天 - MySQL/SQLite操作 - 数据库备份脚本 - 练习:监控数据存储系统

数据库实战入门&#xff1a;从零构建监控数据存储系统 前言 在物联网和系统监控领域&#xff0c;数据存储是核心基础环节。本文将通过MySQL/SQLite操作、数据库备份脚本和监控数据存储实战三个模块&#xff0c;带领初学者快速掌握数据库在真实场景中的应用。文章包含25个代码…...

编写文生视频提示词,制作抖音爆款视频

编写文生视频提示词&#xff0c;制作抖音爆款视频 一、理解文生视频提示词1.1 定义提示词1.1.1 提示词与创作工具的关系1.1.2 文生视频的功能 1.2 提示词的组成1.2.1 主体&#xff08;Subject&#xff09;1.2.2 动作&#xff08;Action&#xff09;1.2.3 场景&#xff08;Scene…...

Linux: 线程控制

目录 一 前言 二 线程控制 1. POSIX线程库(原生线程库) 2. 创建线程 2.1 pthread_create 2.2pthread_self()获取线程id 3.线程终止 3.1.return 方式 3.2 pthread_exit 4 线程等待 三 理解线程tid 一 前言 在上一篇文章中我们已经学习了线程的概念&#xff0c;线程的创…...

为什么 npm list -g 没显示 node_modules?✨

揭秘&#xff1a;为什么 npm list -g 没显示 node_modules&#xff1f;&#x1f575;️‍♂️✨ 嗨&#xff0c;各位代码探险家&#xff01;&#x1f44b; 今天我们要破解一个 npm 小谜团&#xff1a;运行 npm list -g --depth0 时&#xff0c;为什么输出的路径里看不到 node_…...

华为数字芯片机考2025合集4已校正

单选 1. 题目内容 影响芯片成本的主要因素是 Die Size 和封装&#xff0c;但电源、时钟等因素&#xff0c;特别是功耗对解决方案的成本影响较大&#xff0c;因此低成本设计需要兼顾低功耗设计&#xff1a;&#xff08;&#xff09; 1. 解题步骤 1.1 分析题目 Die Size&…...

达摩院Paraformer-ONNX模型:一站式高精度中文语音识别工业级解决方案

文章目录 核心技术创新三大部署方案对比1. Docker极简部署&#xff08;推荐&#xff09;2. Python API直连调用3. 客户端实时测试工具 高阶调优技巧典型应用场景高频问题解决方案参考 阿里达摩院推出的speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-on…...

Llama 4的争议

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

React七案例下

代码下载 登录模块 用户登录 页面结构 新建 Login 组件&#xff0c;对应结构: export default function Login() {return (<div className{styles.root}><NavHeader className{styles.header}>账号登录</NavHeader><form className{styles.form}>&…...

Rust包管理与错误处理

文章目录 包管理箱&#xff08;Crate&#xff09;包&#xff08;Package&#xff09;模块&#xff08;Module&#xff09;访问权限use关键字 错误处理不可恢复错误可恢复错误错误传递kind方法 包管理 Rust的包管理有三个重要的概念&#xff0c;分别是箱、包、模块 箱&#xf…...

关于gitee的readme文档中的图片问题

使用markdown编辑readme文档&#xff0c;需要注意 添加图片&#xff0c;但是不显示问题 1.记得连图片一起上传到仓库中&#xff0c;不能只是在本地markdown文件中复制就结束了&#xff0c;因为存储的是本地图片地址&#xff0c;上传后找不到的 2.注意使用网络地址&#xff0…...

记录vscode连接不上wsl子系统下ubuntu18.04问题解决方法

记录vscode连接不上wsl子系统下ubuntu18.04问题解决方法 报错内容尝试第一次解决方法尝试第二次解决方法注意事项参考连接 报错内容 Unable to download server on client side: Error: Request downloadRequest failed unexpectedly without providing any details… Will tr…...

aws平台练习

注册 AWS 账户 访问 AWS 官方网站&#xff0c;点击“免费注册”按钮&#xff0c;按照提示完成账户注册&#xff1a; 提供电子邮件地址、密码和电话号码。 验证身份&#xff08;可能需要手机验证码&#xff09;。 设置 billing 信息。 2. 登录 AWS 管理控制台 使用注册的邮箱和…...

实战篇-梳理时钟树

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据 总结 前言 这是B站傅里叶的猫视频的笔记 一、建立工程 以Vivado的wave_gen为例子。为了引入异…...

【Hadoop入门】Hadoop生态之Hive简介

1 什么是Hive&#xff1f; 1.1 Hive概述 在大数据时代&#xff0c;如何让传统的数据分析师和SQL开发人员也能轻松处理海量数据&#xff1f;Hive应运而生。Hive是基于Hadoop构建的一套数据仓库分析系统&#xff0c;它提供了一种类似SQL的查询语言&#xff08;HQL&#xff09;&a…...

DSP复习【3章】

F2812提供了XINTF用于扩展并行接口的外设芯片。 XINTF&#xff08;外部接口&#xff09;所需的时钟是 SYSCLKOUT 和 XTIMCLK。 所以正确答案是&#xff1a; ✅ SYSCLKOUT 和 XTIMCLK 什么是XREADY信号&#xff0c;如何使用&#xff1f; 章节例题&#xff1a; 1. 如何通过软件判…...

Hadoop案例——流量统计

Hadoop案例——流量统计 在大数据时代&#xff0c;流量统计是许多企业和组织的关键需求之一。通过分析网络流量数据&#xff0c;企业可以优化网络资源分配、提升用户体验、制定精准的营销策略等。本文将介绍如何使用 Hadoop 框架实现一个简单的流量统计案例&#xff0c;包括数…...

Linux管道 有名管道(FIFO)工作机制全解:从理论到实践

有名管道&#xff08;重要&#xff09; 有名管道/命名管道&#xff0c;主要用于没有血缘关系进程间的通信 当然也支持有血缘关系的情况&#xff0c;只是如果有血缘关系&#xff0c;没有必要使用有名管道&#xff0c;无名管道效果更佳 引入 好了&#xff0c;现在使用条件有了…...

java基础-修饰符

java修饰符 修饰符分类访问修饰符的作用域代码说明访问修饰符总览 非访问修饰符staticfinalabstractsynchronizedvolatiletransientnativestrictfp非访问修饰符总览表 非访问修饰符组合与冲突规则 修饰符分类 分类&#xff1a;访问修饰符 和 非访问修饰符 1.访问修饰符 公共…...

解锁基因密码之重测序(从测序到分析)

在生命科学的奇妙世界中&#xff0c;基因恰似一本记录着生命奥秘的“天书”&#xff0c;它承载着生物体生长、发育、衰老乃至疾病等一切生命现象的关键信息。而重测序技术&#xff0c;则是开启基因“天书”奥秘的一把神奇钥匙。 试想&#xff0c;你手中有一本经典书籍的通用版…...

当使用 Docker Desktop 启动 Tomcat 镜像时时间不对

当使用 Docker Desktop 启动 Tomcat 镜像时时间不对&#xff0c;可能由以下原因导致并可采取相应解决方法&#xff1a; 宿主机时间设置问题&#xff1a;Docker 容器的时间是由宿主机提供的&#xff0c;如果宿主机的时间不正确&#xff0c;那么容器的时间也会不正确。需确保宿主…...

golang gmp模型分析

思维导图&#xff1a; 1. 发展过程 思维导图&#xff1a; 在单机时代是没有多线程、多进程、协程这些概念的。早期的操作系统都是顺序执行 单进程的缺点有&#xff1a; 单一执行流程、计算机只能一个任务一个任务进行处理进程阻塞所带来的CPU时间的浪费 处于对CPU资源的利用&…...