十一届蓝桥杯javaB组试题
以下题目的来源:呆毛王~,我提供自己的解题思路。
算法思想:
暴搜,1到2020一共包含多少个2?
public class Main {
public static void main(String[] args) {
int count=0;
//1到2020一共包含多少个2
for(int i=1;i<=2020;i++) {
String temp=i+"";
for(int j=0;j<temp.length();j++) {
if(temp.charAt(j)=='2') {
count++;
}
}
}
System.out.println(count);
}
}
#答案:624
算法思想:
考察文件读写,我列了两种方法。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
// BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream("F:\\2020.txt")));
// String s="";
// char [][]arr=new char[300][];
// int cur=0;
// int ans=0;
// while((s=bf.readLine())!=null)
// {
// arr[cur++]=s.toCharArray();
// }
char[][] arr=new char[300][];
Scanner scanner=new Scanner(new File("F:\\2020.txt"));
for(int i=0;i<300;i++) {
arr[i]=scanner.nextLine().toCharArray();
}
int count=0;
//暴力搜索
for(int i=0;i<arr.length;i++) {
for(int j=0;j<arr[0].length;j++) {
if(arr[i][j]=='2') {
//向下判断
if(i+3<=arr.length-1) {
if(arr[i+1][j]=='0'&&arr[i+2][j]=='2'&&arr[i+3][j]=='0') {
count++;
}
}
//向右判断
if(j+3<=arr[0].length-1) {
if(arr[i][j+1]=='0'&&arr[i][j+2]=='2'&&arr[i][j+3]=='0') {
count++;
}
}
//向右下角判断
if(i+3<=arr.length-1&&j+3<=arr[0].length-1) {
if(arr[i+1][j+1]=='0'&&arr[i+2][j+2]=='2'&&arr[i+3][j+3]=='0') {
count++;
}
}
}
}
}
System.out.println(count);
}
}
#答案:16520
算法思想:
模拟,注意数组越界问题
public class Main {
public static void main(String[] args) {
int[][] arr=new int[50][50];
//模拟将数组填满的过程
arr[0][0]=1;
//这是我们的起始位置
int i=0;
int j=1;
int count=2;
while(true) {
//这是循环终止的条件
if(arr[19][19]!=0) {
break;
}
//从(0,1)位置开始模拟过程
//从右上到左下
while(j>0){
arr[i][j]=count++;
i++;
j--;
}
//此时j=0
arr[i][j]=count++;
//向下移一位
i++;
//从左下到右上
while(i>0) {
arr[i][j]=count++;
i--;
j++;
}
//此时i==0
arr[i][j]=count++;
//向右移一位
j++;
}
//打印输出
for(int a=0;a<arr.length;a++) {
for(int b=0;b<arr[0].length;b++) {
System.out.print(arr[a][b]+" ");
}
System.out.println();
}
System.out.println(arr[19][19]);
}
}
#答案:761
算法思想:
组合问题+并查集
import java.util.ArrayList;
import java.util.List;
public class Main {
private static int[] parent=new int[1000];
private static int[][] arr;
private static void init(int[] parent) {
for(int i=0;i<parent.length;i++) {
parent[i]=i;
}
}
private static int find(int x) {
if (x == parent[x]) {
return x;
} else {
return parent[x] = find(parent[x]);
}
}
private static boolean unite(int x, int y) {
int root1 = find(x);
int root2 = find(y);
if (root1 == root2) {
return false;
}
parent[root1] = root2;
return true;
}
public static void main(String[] args) {
//组合问题+并查集
int[] arr1= {1,2,3,4,5,6,7};
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
arr=new int[8][8];
arr[1][2] = 1;
arr[1][6] = 1;
arr[2][1] = 1;
arr[2][3] = 1;
arr[2][7] = 1;
arr[3][4] = 1;
arr[3][7] = 1;
arr[3][2] = 1;
arr[4][3] = 1;
arr[4][5] = 1;
arr[5][4] = 1;
arr[5][6] = 1;
arr[5][7] = 1;
arr[6][1] = 1;
arr[6][7] = 1;
arr[6][5] = 1;
arr[7][2] = 1;
arr[7][6] = 1;
arr[7][5] = 1;
arr[7][3] = 1;
for(int i=1;i<=7;i++) {
//这里的i代表了组合的元素个数
dfs(res,path,arr1,i,1);
}
for(List<Integer> elem:res) {
System.out.println(elem);
}
}
private static void dfs(List<List<Integer>> res,List<Integer> path,int[] arr1,int n,int begin) {
if(path.size()==n) {
//递归终止条件
if(check(path)) {
res.add(new ArrayList<>(path));
return;
}
return;
}
for(int i=begin;i<=7;i++) {
path.add(i);
dfs(res,path,arr1,n,i+1);
//回溯
path.remove(path.size()-1);
}
}
private static boolean check(List<Integer> list) {
init(parent);
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
if (find(list.get(i)) != find(list.get(j)) && arr[list.get(i)][list.get(j)] == 1){
//满足连通性,建立连接
unite(list.get(i),list.get(j));
}
}
}
//查看根节点的个数
int count=0;
for (int i=0;i<list.size();i++){
if (parent[list.get(i)]==list.get(i)){
count++;
}
}
return count==1;
}
}
答案:80
算法思想:
这题就是算逆序数,我的思想是从26个字母中挑出15个以上的字母为一个组合(14以下就算是完全颠倒都不能到达100),判断该组合的逆序数是否是100.这条题了解思想就好,以下代码修改数据能通过数据规模较小的测试。比如我测试的【a,b,c,d,e,f】中逆序为10的字符串是可以的。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
boolean[] used=new boolean[26];
//从26个字母中挑出15+个
dfs(res,path,used);
for(List<Integer> elem:res) {
// System.out.println(elem);
for(Integer el:elem) {
System.out.print((char)(el+'a'));
}
System.out.println();
}
}
private static void dfs(List<List<Integer>> res,List<Integer> path,boolean[] used) {
if(path.size()==15) {
if(check(path)) {
res.add(new ArrayList<>(path));
}
}
for(int i=0;i<26;i++) {
if(!used[i]) {
path.add(i);
used[i]=true;
dfs(res,path,used);
used[i]=false;
path.remove(path.size()-1);
}
}
}
//判断逆序和是否等于100
private static boolean check(List<Integer> path) {
int count=0;
for(int i=0;i<path.size()-1;i++) {
for(int j=i+1;j<path.size();j++) {
if(path.get(i)>path.get(j)) {
count++;
}
}
}
return count==100;
}
}
#答案:jonmlkihgfedcba
算法思想:
考察保留小数点后几位
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int max=0;
int min=100;
int sum=0;
for(int i=0;i<n;i++) {
int temp=scanner.nextInt();
sum+=temp;
if(temp>max) {
max=temp;
}else if(temp<min) {
min=temp;
}
}
System.out.println(max);
System.out.println(min);
// System.out.println(String.format("%.2f", (double)sum/n));
System.out.printf("%.2f",(double)sum/n);
}
}
算法思想:
会一点数据结构就能写出来
import java.util.Hashtable;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
Hashtable<Character, Integer> table=new Hashtable();
for(int i=0;i<s.length();i++) {
if(table.containsKey(s.charAt(i))){
int num=table.get(s.charAt(i));
table.put(s.charAt(i), num+1);
}else {
//如果hash表中没有该字符
table.put(s.charAt(i), 1);
}
}
int max=0;
char c=' ';
for(Character elem:table.keySet()) {
if(table.get(elem)>max) {
max=table.get(elem);
c=elem;
}
}
System.out.println(c);
System.out.println(max);
}
}
算法思想:
简单dp,注意区分奇偶,因为题目要求向左下走的次数与右下走的次数相差不能超过1。要么是最底层中间的那个要么就是最底层中间两个中的一个。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int[][] arr=new int[n][n];
for(int i=0;i<arr.length;i++) {
for(int j=0;j<=i;j++) {
arr[i][j]=scanner.nextInt();
}
}
for(int i=1;i<arr.length;i++) {
for(int j=0;j<=i;j++) {
if(j==0) {
arr[i][j]+=arr[i-1][j];
}else if(j==i) {
arr[i][j]+=arr[i-1][j-1];
}else {
arr[i][j]+=Math.max(arr[i-1][j-1], arr[i-1][j]);
}
}
}
if(n%2==1) {
System.out.println(Math.max(arr[n-1][n/2], arr[n-1][n/2+1]));
}else {
System.out.println(arr[n-1][n/2]);
}
}
}
算法思想:
对60%的测试数据可以采用以下代码。
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
//HashSet<String> set=new HashSet();
int count=0;
for(int i=0;i<s.length();i++) {
for(int j=i;j<s.length();j++) {
String temp=s.substring(i, j+1);
count+=function(temp);
}
}
System.out.println(count);
}
private static int function(String s) {
//不同字符的个数
HashSet<Character> set=new HashSet();
for(int i=0;i<s.length();i++) {
set.add(s.charAt(i));
}
return set.size();
}
}
算法思想:
不想写,题目太长。