【蓝桥杯备考资料】如何进入国赛?

目录

  • 写在前面
  • 注意事项
    • 数组、字符串处理
    • BigInteger
    • 日期问题
    • DFS
  • 2013年真题Java B组
    • 世纪末的星期
    • 马虎的算式
    • 振兴中华
    • 黄金连分数
    • 有理数类(填空题)
    • 三部排序(填空题)
    • 错误票据
    • 幸运数字
    • 带分数
    • 连号区间数
  • 2014年真题蓝桥杯Java B组
    • 03猜字母
    • 06奇怪的分式
    • 07扑克牌序列
    • 08分糖果
    • 09地宫取宝
    • 10矩阵翻硬币
  • 2015年真题Java B组
    • 01三角形面积(结果填空3’)
    • 02立方变自身(结果填空5’)
    • 03三羊开泰(结果填空9’)
    • 04循环节长度(代码填空11’)
    • 05九数组分数(代码填空15’)
    • 06加法变乘法(结果填空17’)
    • 07牌型种数(结果填空21’)
    • 08饮料换购(程序设计13’)
    • 09垒骰子(程序设计25’)
  • 2021年真题Java B组
    • 结果填空
    • 1.计算ASC码(5’):
    • 2.卡片表示数字(5‘):
    • 3.直线(15’):
    • 4.货物堆放(10‘):
    • **5.路径(15’)(最短路径问题)
    • 代码编程
    • 6.时间显示(15‘)
    • **7.最少砝码(15’)
    • *8.杨辉三角(20')
    • *9.双向排序(25’)==
    • **10.括号排序(25')
  • 2021年第二场Java B组
    • 质因子与完全平方数
    • DFS(递归回溯)

写在前面

蓝桥杯整体而言难度并不大,我在考前很长一段时间有坚持刷力扣,顺利省一,进入国赛拿到国二。我主要使用的是Java语言,报名的是Java B组,以下是一些小TIPS。祝大家都能取得理想成绩

  • JDK版本:Window->Preferences->Compiler
  • 自动补全:Window->Preferences->Java->Editor->Content Assist:
    .ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz

注意事项

下面介绍的四个内容是蓝桥杯中常考的,包括数组、字符串的处理,BigInteger,日期问题,DFS

数组、字符串处理

  • 读入大量数据:Scanner sc = new Scanner (new BufferedInputStream(System.in))
    数组翻转:int[] intArray = { 1, 2, 3, 4, 5 };
    ArrayUtils.reverse(intArray);
    System.out.println(Arrays.toString(intArray));

  • 进制转换:Integer.valueOf(“str”,x); ///可以为任意进制的字符串str转换成x进制的10进制数
    String str1 = Integer.toHexString(x) ;
    String str2 = Integer.toOctalString(x) ; ///10进制转换成8进制的字符串

  • 读入String,存为char数组

    Scanner sc = new Scanner(System.in);
    String string=sc.next();
    string = String.valueOf(int a)
    char[]a=string.toCharArray();
    Character.isUpperCase(a[1]);
    a[1]>=‘0’;

  • 字符与数字转换
    a.charAt(i)-‘a’->int
    (char)(‘a’+index)

  • 去重
    HashSet set=new HashSet();
    for(int j=i;j set.add(a[j]);
    num+=set.size();
    }

BigInteger

浮点数的比较可以使用:BigDecimal.compareTo(f2) == 0

BigDecimal bigDecimal = new BigDecimal(12.52);
		BigInteger []aBigIntegers=new BigInteger[2030];
		aBigIntegers[0]=BigInteger.ZERO;
		aBigIntegers[1]=BigInteger.ONE;
		aBigIntegers[2]=BigInteger.ONE;
		for(int i=3;i<2030;i++) {
			aBigIntegers[i]=aBigIntegers[i-1].add(aBigIntegers[2]);
		}

日期问题

计算星期几:

      Calendar anCalendar=Calendar.getInstance();
    	anCalendar.set(2022, 3, 7);#月份从0开始
    	System.out.println(anCalendar.get(Calendar.DAY_OF_WEEK) - 1);

日期格式化:

SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
		Date dat1=format.parse("1921-7-23");
		int b=(int)dat1.getTime();

有年/月/日的,有采用月/日/年的,还有采用日/月/年的000

Scanner cin = new Scanner(System.in);
		String a[] = cin.next().split("/");
		String t[] = new String[3];
		t[0] = ((Integer.valueOf(a[0]) >= 60) ? "19" + a[0] : "20" + a[0]) + "-" + a[1] + "-" + a[2];
		t[1] = ((Integer.valueOf(a[2]) >= 60) ? "19" + a[2] : "20" + a[2]) + "-" + a[0] + "-" + a[1];
		t[2] = ((Integer.valueOf(a[2]) >= 60) ? "19" + a[2] : "20" + a[2]) + "-" + a[1] + "-" + a[0];
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		sf.setLenient(false);
		Set<String> s = new TreeSet<String>();
		for (String T : t) {
			try {
				sf.parse(T);
			} catch (ParseException e) {
				continue;
			}
			s.add(T);
		}
		for(String T:s)
		System.out.println(T);
	}

DFS

import java.io.BufferedInputStream;
import java.util.Scanner;

public class _04试剂问题 {

	static int sum=0 ,cnt=Integer.MAX_VALUE;
	static int []arr=new int[15];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Scanner scanner=new Scanner(new BufferedInputStream(System.in));
		for(int i=0;i<15;i++) {
			arr[i]=scanner.nextInt();
			sum+=arr[i];
		}
		dfs(0,0);
		System.out.println(cnt);

	}
	private static void dfs(int d,int v) {
		// TODO Auto-generated method stub
		if(d==15)
			cnt=Math.min(cnt, Math.abs(sum-v-v));
		else {
			dfs(d+1, v+arr[d]);
			dfs(d+1,v);
		}
		
	}

}

2013年真题Java B组

世纪末的星期

1999年的12月31是周五,求最近的哪个99年12月31日是星期天?

  • 日期API-Calendar,1970年以后的可以用
public class _01世纪末的星期 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Calendar calendar= Calendar.getInstance();//获取实例
		for(int year=1999;year<10000;year+=100) {
			calendar.set(Calendar.YEAR, year);
			calendar.set(Calendar.MONTH, 11);//设置12月
			calendar.set(Calendar.DAY_OF_MONTH, 31);
			if(calendar.get(Calendar.DAY_OF_WEEK)==1) {
				System.out.println(year);
				break;
			}
		}
				
		Calendar calendar2=Calendar.getInstance();
		calendar2.set(1999, 11, 31, 0, 0);
		if(calendar2.get(Calendar.DAY_OF_WEEK)==6) {
			System.out.println(1999);			
		}		
		}
}

马虎的算式

满足:abcde=adbce (abcde代表1-9的不同的五个数字)的算式一共有多少种?

  • 枚举法解题,for循环嵌套if判断为不等

振兴中华

从我做起振兴中华,有几种路线?

  • dfs 递归 重复 变化 边界
public class _03振兴中华 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int ans=f(0,0);
		System.out.println(ans);
	}
	private static int f(int i,int j) {
		if(i==3||j==4) return 1;
		return f(i+1,j)+f(i,j+1);		
	}
}

黄金连分数

保留100位小数

  • 前几项寻找规律为斐波拉契数列相邻两项的除
  • double无法表示100位小数,用BigInteger和BigDecimal
public class _04黄金连分数 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BigInteger a=BigInteger.ONE;
		BigInteger b=BigInteger.ONE;
		for(int i=3;i<10000;i++) {
			BigInteger t=b;
			b=a.add(b);
			a=t;
		}
		BigDecimal divide=new BigDecimal(a,110).divide(new BigDecimal(b,110),BigDecimal.ROUND_HALF_DOWN);
		System.out.println(divide.toPlainString().substring(0, 103));
	}
}

有理数类(填空题)

填空题:分数加法的补充

  • static class
return new Rational(this.ra*x.rb+x.ra*this.rb, this.rb*x.rb);

privata long gcd(long  a ,long b){
   if(b==0)  return a;
   return gcd(b, a%b);
 }   

三部排序(填空题)

填空题:整型数组中的数进行分类排序,负数在左端,正数在右端,0在中间,一次完成

  • 快速排序
  p++

  int []arr= {1,2,3,4,5,6};
  Arrays.sort(arr);
  for(int i=0;i<arr.length;i++) {
	  System.out.print(arr[i]+" ");
 }

错误票据

ID连续,开始的数字随机,一个ID重复,一个ID断号

输入:行号+每行内容不等的数据
2
5 6 8 11 9
10 12 9
输出:断号n,重复m
7 9

  • ArrayList是Java的链表类
  • list.add(“a”),list.add(2,“a”),list.get(i),list.remove(i),list.remove(“a”)
  • 对于输入数据的处理scanner.nextLine(); //吃掉整数后面的换行符
  • if(list.get(i).equals(list.get(i-1))) //集合元素使用equals进行比较
    b=list.get(i);
  • list.add(Integer.parseInt(split[j]));
public class _07 错误票据{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		ArrayList<Integer> list=new ArrayList<Integer>();
		int N=scanner.nextInt();
		scanner.nextLine(); //吃掉整数后面的换行符
		for(int i=0;i<N;i++) { //数据处理
			String line =scanner.nextLine();
			String[] splitStrings=line.split(" ");
			for(int j=0;j<splitStrings.length;j++) {
				list.add(Integer.parseInt(splitStrings[j]));
			}
		}		
		Collections.sort(list);
		int a=0,b=0; //局部变量
		for(int i=1;i<list.size();i++) {
			if(list.get(i)-list.get(i-1)==2) 
				a=list.get(i)-1;
			if(list.get(i).equals(list.get(i-1))) //集合元素使用equals进行比较
				b=list.get(i);
		}
		System.out.println(a+" "+b);
	}
}

``

幸运数字

幸运数字1,删去被2整除的数,得3为第二个幸运数字

import java.util.Scanner;

public class _08幸运数 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int m=sc.nextInt();
		int n=sc.nextInt();
		int[] a=new int[n];
		for(int i=0;i<n;i++) 
			a[i]=i*2+1;
		
		int l=1;//幸运数字下标为1,a[l]是幸运数字
		while(true) {
		int p=l+1;
		 for(int i=l+1;i<n;i++) {
			if((i+1)%a[l]==0) {}
			else{
				a[p]=a[i];
				p++;
			}			
		 }
		l++;
		if(a[l]>=n) break;
		}		
		int ans=0;
		for(int i=0;i<n;i++) {
			if(a[i]>=n) break;
			if(a[i]>m) ans++;			
		}		
	}
}

带分数

100表示为100=3+69258/714,1~9不重复,有11种表示方法
输出有多少种?

  • 递归框架求全排列
import java.util.Scanner;

public class _09带分数 {
	
	static int ans;
	private static int N;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		N=sc.nextInt();
		int[] arr= {1,2,3,4,5,6,7,8,9};
		f(arr,0);
		System.out.println(ans);
	}
   //确认某一个排列的第k位
	private static void f(int[] arr, int k) {
		// TODO Auto-generated method stub
		if(k==9) {//全部确认
			check(arr);
			return;
		}
		//选定第k位
		for(int i=k;i<arr.length;i++) {
			int t=arr[i];
			arr[i]=arr[k];
			arr[k]=t;
			
			//移交下一层去确认k+1位
			f(arr, k+1);
			
			//回溯
			t=arr[i];
			arr[i]=arr[k];
			arr[k]=t;
		}
	}
	
private static void check(int[] arr) {
	// TODO Auto-generated method stub
	for(int i=1;i<=7;i++) {
		int num1=toInt(arr,0,i);//加号前的数
		if(num1>=N) continue;
		for(int j=1;j<=8-i;j++) {
			int num2=toInt(arr, i, j);
			int num3=toInt(arr, i+j, 9-i-j);
			if(num2%num3==0&&num1+num2/num3==N)
				ans++;
		}
	}
}
private static int toInt(int[] arr, int pos, int length) {
	// TODO Auto-generated method stub
	int t=1;
	int ans=0;
	for(int i=pos+length-1;i>=pos;i--) {
		ans+=arr[i]*t;
		t*=10;
	}
	return ans;
 }
}

连号区间数

  • 判断ij连续区间,最大-最小
import java.util.Scanner;

public class _10连号区间数 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int[] arr=new int[n+1];
		for(int i=1;i<=n;i++) 
			arr[i]=sc.nextInt();
		int ans=0;
		for(int i=1;i<=n;i++) {
			int max=arr[i];
			int min=arr[i];
			for(int j=i;j<=n;j++) {
				if(arr[j]>max) max=arr[j];
				if(arr[j]<min) min=arr[j];
				if(i==j) ans++;
				else{//判断ij连续区间,最大-最小
					if(max-min==j-i)
						ans++;					
			}
		}
	}
 }
}

2014年真题蓝桥杯Java B组

03猜字母

把abcd…s共19个字母组成的序列重复拼接106次,得到长度为2014的串。

接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。

得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。

答案是一个小写字母,请通过浏览器提交答案。不要填写任何多余的内容。

public class _03猜字母 {

   public static void main(String[] args) {
   	// TODO Auto-generated method stub
   	String s="abcdefghijklmnopqrs";//abcdefghijklmnopqrs
   	String ss="";
   	for(int i=0;i<106;i++) {
   		ss+=s;
   	}
   	
   	char[] a=ss.toCharArray();//构造数组
   	int len=a.length;
   	while(len>1){//对数组进行删除
   		int k=0;
   		for(int i=0;i<len;i++) {
   			if(i%2!=0)//下标为偶数,个数为奇数,删除
   			a[k++]=a[i];
   			else len--;		
   		}
   		for(int i=0;i<len;i++) {
   		System.out.print(a[i]);
   		}
   		System.out.println();
   		
   	}
   	System.out.println(a[0]);

   }
}

06奇怪的分式

上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:

1/4 乘以 8/5

小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45

老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!

对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?

请写出所有不同算式的个数(包括题中举例的)。

显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。

但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!

注意:答案是个整数(考虑对称性,肯定是偶数)。请通过浏览器提交。不要书写多余的内容。

public class _06奇怪的分式 {

	public static void main(String[] args) {
		int sum = 0;
		for (int a = 1; a < 10; a++)
			for (int b = 1; b < 10; b++)
				for (int c = 1; c < 10; c++)
					for (int d = 1; d < 10; d++)
						if (a != b && c != d
								&& a * c * (b * 10 + d) == b * d * (a * 10 + c)) {
							System.out.println(a + "/" + b + " " + c + "/" + d);
							sum++;
						}
		System.out.println(sum);
	}

}

07扑克牌序列

A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。
要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。

请填写出所有符合要求的排列中,字典序最小的那个。

例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。
请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格。

public class _07扑克序列 {
	static char[]a= {'4','4','2','2','3','3','A','A'};
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		f(0);
		
	}
	
	static void f(int k) {
		if(k==8) {
			String s=new String(a);
			
	//System.out.println(s);
			if(check(s)==true) {
				System.out.println(s);
			}
		}
		
		for(int i=k;i<8;i++) {
			{
				char t=a[k];
			a[k]=a[i];
			a[i]=t;
			}
			
			f(k+1);
			
			{
			char t=a[k];
			a[k]=a[i];
			a[i]=t;
			}
		}
		
	}

	static boolean check(String s) {
		if(s.lastIndexOf('A')-s.indexOf('A')==2
				&&
				s.lastIndexOf('2')-s.indexOf('2')==3&&
				s.lastIndexOf('3')-s.indexOf('3')==4&&
				s.lastIndexOf('4')-s.indexOf('4')==5
				)
			return true;
		return false;
		
	}
	
	

}

08分糖果

有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:

每个小朋友都把自己的糖果分一半给左手边的孩子。

一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。

反复进行这个游戏,直到所有小朋友的糖果数都相同为止。

你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。

import java.util.Scanner;
public class _08分糖果 {//添加一个数组用于储存每个孩子手中的糖果数的一半

	public static void main(String[] args) {
		int sum = 0;
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int a[] = new int[n + 1];
		int f[] = new int[n + 1];
		for (int i = 0; i < n; i++) {
			a[i] = sc.nextInt();//输入糖果数
			f[i] = a[i] / 2;
		}
		int flag = 1;
		while (flag == 1) {
			flag = 0;
			for (int i = 0; i < n - 1; i++) {
				if (a[i] != a[i + 1])//糖果数相等时退出循环
					flag = 1;
			}
			if (flag == 1) {
				for (int i = 0; i < n; i++) {
					if (i == n - 1)//最右边的小朋友每轮过后剩的糖果数
						a[i] = a[i] / 2 + f[0];
					else//其他小朋友每轮过后剩的糖果数
						a[i] = a[i] / 2 + f[i + 1];
				}
				for (int i = 0; i < n; i++) {
					if (a[i] % 2 == 1) {//当前糖果数为奇数
						a[i] += 1;
						f[i] = a[i] / 2;
						sum++;
					} else
						f[i] = a[i] / 2;
				}
			}
		}
		System.out.println(sum);
	}


}

09地宫取宝

X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。

地宫的入口在左上角,出口在右下角。

小明被带到地宫的入口,国王要求他只能向右或向下行走。

走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。

当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。

请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

输入

输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)

接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值

输出
要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。

样例输入
2 3 2
1 2 3
2 1 5
样例输出
14

import java.util.Scanner;
 
public class _09地宫取宝 {
 
	static int[][] a = new int[55][55],flag = new int[55][55];
	static int ans = 0,n,m,k;
 
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		m = in.nextInt();
		k = in.nextInt();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = in.nextInt();
			}
		}
		bfs(0,0,-1,0);//-1记录的是宝贝的价值
		System.out.println(ans);
		
		
	}
 
	private static void bfs(int i, int j, int max, int x) {
		int cur = a[i][j];//当前宝贝的价值
		if(i >= n || j >= m || x > k) {
			return;
		}
		if(i == n-1 && j == m-1 ) {//走到出口
			if (x == k || (x == k-1 && cur > max)) {
				ans++;
				ans = ans % 1000000007;
			}
			
		}
		//当前宝贝的价值大,并且要拿起它的情况
		if(cur > max) {
			bfs(i+1,j,cur,x+1);
			bfs(i, j+1, cur, x+1);
		}
		//当前宝贝价值小或价值大但不拿当前宝贝的情况
		bfs(i, j+1, max, x);
		bfs(i+1, j, max, x);
	}
}

10矩阵翻硬币

小明先把硬币摆成了一个 n 行 m 列的矩阵。

随后,小明对每一个硬币分别进行一次 Q 操作。

对第x行第y列的硬币进行 Q 操作的定义:将所有第 ix 行,第 jy 列的硬币进行翻转。

其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。

当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。

小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。

聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。
输入格式
  输入数据包含一行,两个正整数 n m,含义见题目描述。
输出格式
  输出一个正整数,表示最开始有多少枚硬币是反面朝上的。
样例输入
2 3
样例输出
1
数据规模和约定
  对于10%的数据,n、m <= 10^3;
  对于20%的数据,n、m <= 10^7;
  对于40%的数据,n、m <= 10^15;
  对于10%的数据,n、m <= 10^1000(10的1000次方)。

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
 
public class Main {
 
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String s1 = in.next();//n
		String s2 = in.next();//m
		BigInteger b1 = sqrt(s1);//根号n
		BigInteger b2 = sqrt(s2);//根号m
		//结果是根号n和根号m的乘积
		System.out.println(b1.multiply(b2));
		
		
	}
 
	private static BigInteger sqrt(String s) {
		BigInteger n = new BigInteger(s);
		int length = s.length();
		int len = 0;//记录根号n是几位数
		if (length % 2 == 0) {
			len = length/2;
		} else {
			len = length/2 + 1;
		}
		char[] a = new char[len];//用字符串存储根号n
		Arrays.fill(a, '0');//字符串用0填充
		//下面开始从根号n的最高位开始猜
		for (int i = 0; i < len; i++) {
			//每一位的数都是由1~9的数字组成的
			for (char j = '1'; j <= '9'; j++) {
				a[i] = j;
				BigInteger t = new BigInteger(String.valueOf(a));
				BigInteger pow = t.pow(2);
				//判断这个数的平方是否比n大,就说明找到了这个数
				if (pow.compareTo(n) == 1) {
					a[i] -= 1;
					break;
				}
			}
		}
		BigInteger b = new BigInteger(String.valueOf(a));
		return b;
		
	}
 
	
}

2015年真题Java B组

01三角形面积(结果填空3’)

02立方变自身(结果填空5’)

观察下面的现象,某个数字的立方,按位累加仍然等于自身。
1^3 = 1
8^3 = 512 5+1+2=8
17^3 = 4913 4+9+1+3=17

请你计算包括1,8,17在内,符合这个性质的正整数一共有多少个?

请填写该数字,不要填写任何多余的内容或说明性的文字。

  • 暴力求解
  • 改进,各位数求和可化为字符串后,sum+=s.charAt(i)-‘0’;
public class _02立方变自身 {
   static boolean isItself(int m){
   	int a=m*m*m;
   	String s=String.valueOf(a);
   	int sum=0;
   	for(int i=0;i<s.length();i++) {
//			sum+=a%10;
//			a=a/10;
   		sum+=s.charAt(i)-'0';
   	}
   	if(sum==m)
   		return true;
   	return false;	
   }
   public static void main(String[] args) {
   	// TODO Auto-generated method stub
   	int cnt=0;
   	for(int i=1;i<100000;i++) {
   		if(isItself(i)==true) {
   			System.out.println(i);
   			cnt++;
   		}
   	}
   	System.out.println(cnt);
   }
}

03三羊开泰(结果填空9’)

观察下面的加法算式:
【蓝桥杯备考资料】如何进入国赛?_第1张图片

其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。

请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。

  • 暴力枚举if(x1==x2) contiue;
  • 全排列


public class _03散养献瑞 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int []a={0,1,2,3,4,5,6,7,8,9};
		dfs(a,0);		
	}
	private static void dfs(int[] a, int m) {
		// TODO Auto-generated method stub
		if(m>10)
			return;
		if(m==10){//结束深搜
			int x = 1000*a[0] + 100*a[1] + 10*a[2] + a[3];
			int y = 1000*a[4] + 100*a[5] + 10*a[6] + a[1];
			int z = 10000*a[4] + 1000*a[5] + 100*a[2] + 10*a[1] + a[7];
			if(a[0]==0 || a[4]==0) //保证位数
				return;
			if(x+y==z)
				System.out.println(x+"+"+y+"=="+z);
	}
		for(int i=m;i<10;i++) {
			int t=a[i];
			a[i]=a[m];
			a[m]=t;
			dfs(a, m+1);
			t=a[i];
			a[i]=a[m];
			a[m]=t;	
		}
}
}

04循环节长度(代码填空11’)

两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。
比如,11/13=6=>0.846153846153… 其循环节为[846153] 共有6位。
下面的方法,可以求出循环节的长度。

请仔细阅读代码,并填写划线部分缺少的代码。

public static int f(int n, int m)
{
    n = n % m;    
    Vector v = new Vector();
    
    for(;;)
    {
        v.add(n);
        n *= 10;
        n = n % m;
        if(n==0) return 0;
        if(v.indexOf(n)>=0)  _________________________________ ;  //填空
    }

*答案: return v.size() - v.indexOf(n);

05九数组分数(代码填空15’)

06加法变乘法(结果填空17’)

我们都知道:1+2+3+ … + 49 = 1225
现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015

比如:
1+2+3+…+1011+12+…+2728+29+…+49 = 2015
就是符合要求的答案。

请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10)。

  • 仔细分析题目,发现可以直接枚举法解决问题,两重循环
public class _06加法变乘法 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for (int i = 1; i < 46; i++) {
			for (int j = i+2; j <48; j++) {
				if((i*(i+1)-(i+i+1)+j*(j+1)-(2*j+1)==2015-1225))
						System.out.println(i+" "+j);				
			}			
		}
	}
}

07牌型种数(结果填空21’)

小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?

请填写该整数,不要填写任何多余的内容或说明文字。

  • 递归求解
  • 好像可以又直接暴力枚举,用13个for循环解决问题,咱考试的时间还是非常充足的
public class _07牌型种类 {
	static int ans = 0;
	static int sum = 0;
	static void dfs(int cur)    //cur取牌的次数,sum手牌的总数
	{
	    if (sum>13)return;
	    if (cur == 13){
	        if (sum == 13) ans++;
	        return;
	    }
	    for (int i = 0; i <= 4; i++){  //13种牌,每种有4张,有五种取法 取0,1,2,3,4张
	        sum += i;
	        dfs(cur + 1);
	        sum -= i;     //还原
	    }    
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	   dfs(0);
	   System.out.println(ans);
	}
}

08饮料换购(程序设计13’)

乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去,但不允许赊账。

请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的n瓶饮料,最后他一共能得到多少瓶饮料。

输入:一个整数n,表示开始购买的饮料数量(0 输出:一个整数,表示实际得到的饮料数

例如:
用户输入:
100
程序应该输出:
149

用户输入:
101
程序应该输出:
151

import java.util.Scanner;
 
public class _08饮料换购_ {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		int sum=n;
		
	  while(n>=3) {
		  sum+=n/3;
		  n=n%3+n/3;
		  
	  }
	  System.out.println(sum);

	}
}

09垒骰子(程序设计25’)

赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。
经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。
假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。 atm想计算一下有多少种不同的可能的垒骰子方式。
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
由于方案数可能过多,请输出模 10^9 + 7 的结果。

不要小看了 atm 的骰子数量哦~

「输入格式」
第一行两个整数 n m
n表示骰子数目
接下来 m 行,每行两个整数 a b ,表示 a 和 b 不能紧贴在一起。

「输出格式」
一行一个数,表示答案模 10^9 + 7 的结果。

「样例输入」
2 1
1 2


public class _09_垒骰子 {
  static int op[] = new int[7];
  private static int n;
  private static int m;
  private static final long MOD = 1000000007;
 
  static void init() {
    op[1] = 4;
    op[4] = 1;
    op[2] = 5;
    op[5] = 2;
    op[3] = 6;
    op[6] = 3;
  }
 
  public static void main(String[] args) {
    init();
    Scanner sc = new Scanner(System.in);
    n = sc.nextInt();
    m = sc.nextInt();
    long conflict[][] = new long[6][6];
    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < 6; j++) {
        conflict[i][j]=1;
      }
    }
    //建立冲突矩阵
    for (int i = 0; i < m; i++) {
      int a = sc.nextInt();
      int b = sc.nextInt();
      conflict[op[a] - 1][b - 1] = 0;
      conflict[op[b] - 1][a - 1] = 0;
    }
    //  求冲突矩阵的n-1次方
    long[][] mPow_n_1 = mPow(conflict, n - 1);
    //累加矩阵的每个元素
    long ans = 0;
    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < 6; j++) {
        ans = (ans + mPow_n_1[i][j]) % MOD;
      }
    }
    //ans*4^n
    System.out.println(ans * power(4, n) % MOD);
  }
 
  private static long power(long i, int n) {
    long ans = 1;
    while (n != 0) {
      if ((n & 1) == 1) ans = (ans * i) % MOD;
      i = i * i % MOD;
      n >>= 1;
    }
    return ans;
  }
 
  /*矩阵的快速幂*/
  private static long[][] mPow(long[][] conflict, int n) {
    long[][] e = new long[6][6];
    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < 6; j++) {
        if (i == j) e[i][j] = 1;
        else e[i][j] = 0;
      }
    }
    while (n != 0) {
      if ((n & 1) == 1) {
        e = mMul(e, conflict);
      }
      conflict = mMul(conflict, conflict);
      n >>= 1;
    }
 
    return e;
  }
 
  private static long[][] mMul(long[][] a, long[][] b) {
    long[][] ans = new long[6][6];
    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < 6; j++) {
        for (int k = 0; k < 6; k++) {
          ans[i][j] = (ans[i][j] + a[i][k] * b[k][j]) % MOD;
        }
      }
    }
    return ans;
  }
}

2021年真题Java B组

结果填空

1.计算ASC码(5’):

‘L’+0

2.卡片表示数字(5‘):

Arrays.fill(v,n);

3.直线(15’):

Set去重StringBuffer.append( )/.toString();
Set< String> set=new HashSet< String>()

4.货物堆放(10‘):

  • long-10^18 12byte=96bit
  • int 10^10
  • static long[] val = new long[101000];

**5.路径(15’)(最短路径问题)

  • Floyd算法
    for(int i,j,k;<2025;++)
    if (gragh[i][k] + gragh[k][j] < gragh[i][j])
    gragh[i][j] = gragh[i][k] + gragh[k][j];

  • 求最小公倍数:i/gcd(i,j)*j

  • 求最小公因数:if(j==0)
    return i;
    return gcd(j, i%j);

代码编程

6.时间显示(15‘)

  • 格式化输出: System.out.format(“%02d”, a);
    System.out.format(“%o\n”,i);//“o"表示格式化输出八进制整数
    System.out.format(”%x\n",i);//"x"表示格式化输出十六进制整数

  • BigInteger
    浮点数的比较可以使用:BigDecimal.compareTo(f2) == 0

BigDecimal bigDecimal = new BigDecimal(12.52);
		System.out.println(bigDecimal);
		BigInteger []aBigIntegers=new BigInteger[2030];
		aBigIntegers[0]=BigInteger.ZERO;
		aBigIntegers[1]=BigInteger.ONE;
		aBigIntegers[2]=BigInteger.ONE;
		for(int i=3;i<2030;i++) {
			aBigIntegers[i]=aBigIntegers[i-1].add(aBigIntegers[2]);
		}
		BigInteger mBigInteger=aBigIntegers[2020];
		BigInteger nBigInteger=aBigIntegers[520];
		System.out.println(f(mBigInteger,nBigInteger));

**7.最少砝码(15’)

*8.杨辉三角(20’)

  • 利用链表构造
    List list=new ArrayList()
    list.addAll(list2)/add(1)
  • 对于list进行遍历:for(Long l: list)
    list.indexOf(2021);

*9.双向排序(25’)==

  • 对于数组进行逆序排序
    Comparator comparator = new Comparator() {
    public int compare(Integer a, Integer b) {
    return b - a;
    }
    };
    Arrays.sort(r, 1, q + 1, comparator);

**10.括号排序(25’)

括号匹配问题
Map.get(‘(’)
Map.containsValue/containsKey
Map.put(‘(’),‘(’)
Stack.empty()/pop()/peek()

public class isMatch {
		public static void main(String[] args) {
		String string ="([a+b]-(rr{}))";
		boolean res =  match(string);
		System.out.println(res);
	}
	public static boolean match(String str) {
		Map<Character,Character> map = new HashMap<>();
		map.put(')', '(');
		map.put(']', '[');
		map.put('}', '{');
		Stack<Character> stack =new Stack<>();
		for(int i=0;i<str.length();i++) {
			Character c =str.charAt(i);
			if(map.containsValue(c)) {//左括号入栈
				stack.push(c);
			}
			else if(map.containsKey(c)) {//右括号出栈匹配
				if(stack.empty()) {
					return false;
				}
				if(stack.peek()==map.get(c)) {
					stack.pop();
				}else {
					return false;
				}
			}
		}
		return stack.empty()?true:false;
	}
}

2021年第二场Java B组

质因子与完全平方数

  • 当前数的所有质因子的指数为偶数,不是偶数就再乘个该质因子

DFS(递归回溯)

import java.util.Scanner;

public class Main {
    static int MOD = 1000000007;
    static int ans = 0;
    static int n, m, k;
    // 方向数组
    static int[] xx = new int[] {1, 1, -1, -1, 2, 2, -2, -2};
    static int[] yy = new int[] {2, -2, 2, -2, 1, -1, 1, -1};
    static int[][] cnt;
    // 是否有马
//    static boolean[][] vis; 不能用vis数组来标记不能放马的位置,因为棋盘上某一点可能有多个马共同进行限制,需要对限制数计数
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        m = scan.nextInt();
        k = scan.nextInt();
        cnt = new int[n][m];
        // 从左上角第一个格子开始放,初始已放马的个数 = 0
        dfs(0, 0, 0);
        System.out.println(ans);
    }
    static void dfs (int x, int y, int horse) {
        if (horse == k) {
            ans = (ans + 1) % MOD;
            return;
        }
        // 切换到下一行第一个元素
        if (y >= m) {
            y = 0;
            x++;
            if (x >= n) return;
        }
        // 当前(x,y)位置不放马
        dfs(x, y + 1, horse);

        // 当前(x,y)位置放马
        // 先判断能否放马
        if (cnt[x][y] == 0) {
            cnt[x][y]++;
            // 遍历当前位置的马能够跳到的棋盘位置,标记为true
            for (int i = 0; i < 8; i++) {
                int tmpx = x + xx[i];
                int tmpy = y + yy[i];
                if (tmpx < 0 || tmpy < 0 || tmpx >= n || tmpy >= m) {
                    continue;
                }
                cnt[tmpx][tmpy]++;
            }
            // 放了马之后继续遍历
            dfs(x, y + 1, horse + 1);
            // 别忘了回溯
            // 回溯:一切在之前change过的变量,全都要恢复
            cnt[x][y]--;
            for (int i = 0; i < 8; i++) {
                int tmpx = x + xx[i];
                int tmpy = y + yy[i];
                if (tmpx < 0 || tmpy < 0 || tmpx >= n || tmpy >= m) {
                    continue;
                }
                cnt[tmpx][tmpy]--;
            }
        }
    }
}

你可能感兴趣的:(算法,蓝桥杯,职场和发展)