十一届蓝桥杯javaB组试题

十一届蓝桥杯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();
	}
}

在这里插入图片描述
在这里插入图片描述
算法思想:
不想写,题目太长。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值