1.动态规划
1.1包子凑数

样例1:
输入:
2 4 5
输出:
6
样例2:
输入:
2 4 6
输出:
INF
1.1.2思路分析
首先我们必须知道一个结论:
对于不定方程:
若a,b互质,那么就有无限多个c使方程有解,即有有限个c使方程无解
若a,b不互质,那么就有无限多个c使方程无解
对于我们每一种:从不同的蒸笼中取几笼的包子来凑成题目中的X的方案,我们可以视为形如的不定方程,那么我们只要判断a,b….c这些数是否互质,如果不互质,那么就输出INF
互质:最大公约数为1!!
这个题目从题型上来看是一个完全背包问题(反正我没做出来),正解是,设是能不能凑出i的集合,如果能凑出则
,如果不能凑出则
。根据题意易知:如果第i个包子能凑出来,那么
个包子也必然能够能凑出来,例如:
有4,5两笼包子,如果能凑出5个包子,对于i=1那么一定能凑出5+4,5+8,5+12个包子
对于i=2,那么一定能凑出5+5,5+10,5+15个包子
1.1.3代码
import java.util.Scanner;/*小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 N 种蒸笼,其中第 i 种蒸笼恰好能放 Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。每当有顾客想买 X 个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有 XX 个包子。比如一共有 3 种蒸笼,分别能放 3、4 和 5 个包子。当顾客想买 11 个包子时,大叔就会选 2 笼 3 个的再加 1 笼 5 个的(也可能选出 1 笼 3 个的再加 2 笼 4 个的)。当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有 3 种蒸笼,分别能放 4、5 和 6 个包子。而顾客想买 7 个包子时,大叔就凑不出来了。小明想知道一共有多少种数目是包子大叔凑不出来的。*/public class Main {public static void main(String[] args) {Scanner sc=new Scanner(System.in);int[] arr=new int[101];int[] dp=new int[10000];int res=0;int count=0;//dp[i]表示能不能凑出i个包子/*对于不定方程ax+by=C,若a,b互质(即最大公约数为1),那么有无限多个C能使方程有解(也即有有限个C使方程无解)若a,b不互质,那么有无限多个C使方程无解*/int N=sc.nextInt();dp[0]=1;for(int i=1;i<=N;i++){arr[i]=sc.nextInt();if(i==1)res=arr[i];else res=gcd(res,arr[i]);for(int j=0;j<10000;j++){if(dp[j]==1&&j+arr[i]<10000)dp[j+arr[i]]=1;}}if(res!=1){System.out.println("INF");}else{for(int i=0;i<dp.length;i++){if(dp[i]==0){count++;}}System.out.println(count);}}public static int quickPower(int A, int n) {if (n == 0)return 1;else if (n % 2 == 1)return quickPower(A, n - 1) * A;else {int temp = quickPower(A, n / 2);return temp * temp;}}public static int gcd(int m,int n){if(m%n==0)return n;return gcd(n,m%n);}}
2.dfs搜索
2.1排列小球

输入:
3 6 0
输出:
3
2.1.1思路分析
题目要求我们求出有多少种严格单调递增序列,我们可以以这样一个枚举思想求解:
先枚举要用小球种类,再枚举该种类使用多少个小球。dfs需要记录的数据有:
- 上一次使用的小球类型
- 上一次使用的小球类型的数量
- 还有多少个小球没有使用
递归退出条件为:剩余没用的小球数量为0,即
2.1.2代码
import java.util.Scanner;public class Main {static int arr[] = new int[3];static int count = 0;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int sum = 0;for (int i = 0; i < arr.length; i++) {arr[i] = sc.nextInt();sum += arr[i];}sc.close();f(sum, 0, -1);System.out.println(count);}private static void f(int sum, int x, int last) {if(sum==0) {count++;return;}for (int i = 0; i < arr.length; i++) {if(i==last)continue;for (int j = x + 1; j <= arr[i] && j <= sum; j++) {arr[i] = arr[i] - j;f(sum - j, j, i);arr[i] = arr[i] + j;}}}}
2.2正则问题
2.2.1思路分析
遇到括号匹配的问题我们首先要想到栈的思想(是思想,而不是栈的具体实现),对于这题,给定一个正则表达式(表达式一定是合法的),我们可以建立这样一个递归的思路:
遇到‘(’我们就将index(index表示游走在正则表达式字符串上的指针,最初指向0)加1,并进入下一层的递归,遇到‘|’就将当前的最大长度和index+1后dfs()求出的最大长度相比较,从而更新最大的长度,遇到‘)’就退出该层栈中的递归,此时的‘)’正匹配开头的‘(’。
2.2.2代码
import java.util.Scanner;public class Main {// 正则问题static String s;static int index = 0;public static void main(String[] args) {Scanner sc = new Scanner(System.in);s = sc.nextLine();System.out.println(dfs());}public static int dfs() {int res = 0;while (index < s.length()) {if (s.charAt(index) == '(') {index++;res += dfs();index++;//为什么dfs()完成以后还要index++呢?/*这是因为,我们遇到了‘(’,那么在res+=dfs()的时候我们就进入了下一层(假设第二层)的递归,在第二层的递归栈中,我们遇到了‘)’,此时我们要退出该层的递归栈并且返回第二层中记录的res,第一层的res得到了更新,但是我们的index此时刚好定位在‘)’所在的位置下标,我们必须将index++才能使递归一直进行到最后的节点*/} else if (s.charAt(index) == '|') {index++;res = Math.max(res, dfs());} else if (s.charAt(index) == ')') {break;} else {res++;index++;}}return res;}}
3.BFS搜索
3.1完全二叉树的权值

输入:
7 1 6 5 4 3 2 1
输出:
2
3.1.1思路分析
求二叉树的每一个层数的权值是多少,说白了就是二叉树的层序遍历,这里因为是一个完全二叉树,我们需要知道完全二叉树的性质:
- 二叉树的深度=
- 当前节点(n)的左右子节点为2n+1,2n+2;
知道这些知识,我们就可以利用bfs逐步搜索二叉树的每一层
3.1.2代码
import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;public class Main {static int index = 0;static int i = 1;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();Node[] arr = new Node[n];int[] num = new int[(int) Math.sqrt(n) + 1];for (int i = 0; i < n; i++) {arr[i] = new Node(i, sc.nextInt());}Queue<Node> q = new LinkedList<Node>();q.offer(arr[0]);while (!q.isEmpty()) {int size = q.size();int sum = 0;for (int i = 0; i < size; i++) {Node cur = q.poll();int curpos = cur.pos;int curcount = cur.count;sum += curcount;if (curpos * 2 + 1 < n) {q.offer(arr[curpos * 2 + 1]);}if (curpos * 2 + 2 < n) {q.offer(arr[curpos * 2 + 2]);}}num[index++] = sum;}int max = num[0];for (int i = 0; i < num.length; i++) {max = Math.max(num[i], max);}for (int i = 0; i < num.length; i++) {if (num[i] == max) {System.out.println(i + 1);break;}}}static class Node {int pos;int count;public Node(int pos, int count) {this.pos = pos;this.count = count;}}}
4.跑步锻炼
第十一届蓝桥杯 ——跑步锻炼java代码
问题描述
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。
如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年10 月 1 日周四(含)。
请问这段时间小蓝总共跑步多少千米?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
————————————————
版权声明:本文为CSDN博主「A.�」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Mumu_777/article/details/115578428
import java.text.SimpleDateFormat;import java.util.Calendar;public class _03跑步锻炼 {public static void main(String[] args) {int sum=2;Calendar c1=Calendar.getInstance();SimpleDateFormat a=new SimpleDateFormat("yyyyMMdd");//设置开始日期c1.set(Calendar.YEAR, 2000);c1.set(Calendar.MONTH, 0);c1.set(Calendar.DAY_OF_MONTH, 1);for (int i = 1; i <=10000; i++) {c1.add(Calendar.DAY_OF_YEAR,1);sum++;//每天都要跑1千米String date=a.format(c1.getTime());//将日期转换成数字数字格式如20000102char b[]=date.toCharArray();if (c1.get(Calendar.DAY_OF_WEEK)==Calendar.MONDAY || (b[6]=='0' && b[7]=='1'))//判断是不是星期一或者是每个月的1号{sum=sum+1;//是的话,额外多跑1千米}//设置结束日期if (date.equals("20201001")) {break;}}System.out.println(sum);//sum=8879}}
