第十二届蓝桥杯大赛软件类省赛Java大学B组(第一场)

一、试题A:ASC

本题总分:5 分

【问题描述】

已知大写字母 A 的 ASCII 码为 65,请问大写字母 L 的 ASCII 码是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【答案】:76

public class Main {	
	public static void main(String[] args) {
		System.out.print((int)'L');
	}
}

二、试题B:卡片

本题总分:5 分

【问题描述】

    小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。

    小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。

    小蓝想知道自己能从 1 拼到多少。

    例如,当小蓝有 30 张卡片,其中 0 到 9 各 3 张,则小蓝可以拼出 1 到 10,

    但是拼 11 时卡片 1 已经只有一张了,不够拼出 11。

    现在小蓝手里有 0 到 9 的卡片各 2021 张,共 20210 张,请问小蓝可以从 1 拼到多少?

    提示:建议使用计算机编程解决问题。

【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【答案】:3181

import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		int k1=2021,k2=2021,k3=2021,k4=2021,k5=2021,k6=2021,k7=2021,k8=2021,k9=2021;
		int i=1;
		while(true){
			int x=i;
			while(x>0){
				switch(x%10){
				case 1:k1--;break;
				case 2:k2--;break;
				case 3:k3--;break;
				case 4:k4--;break;
				case 5:k5--;break;
				case 6:k6--;break;
				case 7:k7--;break;
				case 8:k8--;break;
				case 9:k9--;break;
				}
				x/=10;
			}
			if(k1<0||k2<0||k3<0||k4<0||k5<0||k6<0||k7<0||k8<0||k9<0){  //注意判断是否出界代码的位置
				break;
			}
			i++;
		}
		System.out.print(i-1);
	}
}

在这里插入图片描述

四、试题D:货物摆放

本题总分:10 分

【问题描述】

    小蓝有一个超大的仓库,可以摆放很多货物。

    现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、 宽、高。

    小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上分别堆 L、W、H 的货物,满足 n = L × W × H。

    给定 n,请问有多少种堆放货物的方案满足要求。

    例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、2 × 2 × 1、4 × 1 × 1。

    请问,当 n = 2021041820210418 (注意有 16 位数字)时,总共有多少种方案?

    提示:建议使用计算机编程解决问题。

【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【答案】:2430

分析:

找出2021041820210418的因子,然后对因子进行两层循环。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		long ans=0L,n=2021041820210418L;
		ArrayList<Long> arr=new ArrayList<Long>();
		for(long i=1;i<Math.sqrt(n);i++){
			if(n%i==0){
				arr.add(i);
				arr.add(n/i);
			}
		}
		if((int)Math.sqrt(n)*(int)Math.sqrt(n)==n){
			arr.add((long)Math.sqrt(n));
		}
		for(int i=0;i<arr.size();i++){
			for(int j=0;j<arr.size();j++){
				if(n%(arr.get(i)*arr.get(j))==0){   //两个数相除(a/b)一定要注意精度问题,小数点后面的数会切掉。所以最好用乘然后取余。
					ans++;
				}
			}
		}
		System.out.println(ans++);
	}
}

六、试题F:时间显示

时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分

【问题描述】

    小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 1970 年 1 月 1 日 00:00:00 到当前时刻经过的毫秒数。

    现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要显示出时分秒即可,毫秒也不用显示,直接舍去即可。

    给定一个用整数表示的时间,请将这个时间对应的时分秒输出。

【输入格式】

    输入一行包含一个整数,表示时间。

【输出格式】

    输出时分秒表示的当前时间,格式形如 HH:MM:SS,其中 HH 表示时,值为 0 到 23,MM 表示分,值为 0 到 59,SS 表示秒,值为 0 到 59。时、分、秒不足两位时补前导 0。

【样例输入 1】46800999

【样例输出 1】13:00:00

【样例输入 2】1618708103123

【样例输出 2】01:08:23

【评测用例规模与约定】对于所有评测用例,给定的时间为不超过 1018 的正整数。

分析:

看到与时间有关的题,一定要想到用时间戳来做题!

import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long time=sc.nextLong();
		time=time/1000;    //省略毫秒数
		long tian=time/(24*3600);   
		long timer=time-(tian*24*3600);   //时间戳减去含有的天数的秒数得到一天内的秒数
		long h=timer/3600;         
		long m=timer%3600/60;
		long s=timer%3600%60;
		System.out.printf("%02d:%02d:%02d",h,m,s);
	}
}

七、试题G:最少砝码

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分

【问题描述】

    你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意小于等于 N 的正整数重量。

    那么这套砝码最少需要包含多少个砝码?

    注意砝码可以放在天平两边。

【输入格式】输入包含一个正整数 N。

【输出格式】输出一个整数代表答案。

【样例输入】7

【样例输出】3

【样例说明】

    3 个砝码重量是 1、4、6,可以称出 1 至 7 的所有重量。

    1 = 1;

    2 = 6 − 4 (天平一边放 6,另一边放 4);

    3 = 4 − 1;

    4 = 4;

    5 = 6 − 1;

    6 = 6;

    7 = 1 + 6;

    少于 3 个砝码不可能称出 1 至 7 的所有重量。

【评测用例规模与约定】对于所有评测用例,1 ≤ N ≤ 1000000000。

分析:

动态规划

方法一:找规律之后发现,砝码数成1、3、9、27…的规律,也就是如下
n 最少需要的砝码数
1 1
2 2
3 2
4 2
5 3
6 3
7 3
8 3
9 3
10 3
11 3
12 3
13 3
14 4

以3的指数增加。

方法二:找规律,发现
n 砝码元素
1 1
2 1、3
3 1、3
4 1、3
5 1、3、9
6 1、3、9

13 1、3、9
14 1、3、9、27

40 1、3、9、27

import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int sum=0,i=0,ans=0;
		while(true){
			sum+=Math.pow(3, i);
			ans++;
			if(sum>=n){
				break;
			}
			i++;
		}
		System.out.print(ans);
	}
}

八、试题H:杨辉三角形

时间限制: 5.0s 内存限制: 512.0MB 本题总分:20 分

【问题描述】

    下面的图形是著名的杨辉三角形:

    如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:                                                       
     1,
    1, 1, 
  1, 2, 1, 
 1, 3, 3, 1, 
1, 4, 6, 4, 1, 
...

    给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?

【输入格式】输入一个整数 N。

【输出格式】输出一个整数代表答案。

【样例输入】6

【样例输出】13

【评测用例规模与约定】对于 20% 的评测用例,1 ≤ N ≤ 10;对于所有评测用例,1 ≤ N ≤ 1000000000。

分析:

n为10亿,要么超时要么内存超限

如果暴力做数组开到1000能拿40%分

满分:第二列和第三列有关系,可以发现第三列的数为第二列的前面的数相加之和,也就成等差数列的和。

暴力-通过40%:

import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		long ans=0L;
		long[][] a=new long[2000][2000];
		for(int i=0;i<2000;i++){
			for(int j=0;j<=i;j++){
				if(j==0||j==i){
					a[i][j]=1;
				}else{
					a[i][j]=a[i-1][j]+a[i-1][j-1];
				}
				ans++;
				if(a[i][j]==n){
					System.out.print(ans);
					return;
				}
			}
		}
		/*for(int i=0;i<=n;i++){
			System.out.println(Arrays.toString(a[i]));}*/
	}
}
import java.util.ArrayList;
import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		long ans=0;
		ArrayList<Integer>[] arr=new ArrayList[1000];
		for(int i=0;i<1000;i++){
			arr[i]=new ArrayList<Integer>();
			for(int j=0;j<=i;j++){
				if(j==0||j==i){
					arr[i].add(1);
					ans++;
				}else{
					arr[i].add(arr[i-1].get(j-1)+arr[i-1].get(j));
					ans++;
				}
				if(arr[i].get(j)==n){
					System.out.print(ans);
					return;
				}
			}
		}
		
	}
}

找规律-AC满分

import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long n=sc.nextLong();
		long[] a=new long[44725];    //里面书数可能比10亿还要大,所以定义long型
		a[0]=1;
		if(n==1){System.out.print(1);return;}
		for(int i=1;i<=44724;i++){
			for(int j=i;j>=1;j--){     
				a[j]=a[j]+a[j-1];     //每一行的数都和上一行的数有关,有点像01背包的优化思想
				if(a[j]==n){          //因为这里要判断是否相等,所以最好定义n为long型,如果定义为int类型判断时会造成精度丢失而错误。
					System.out.print(i+(i*(i-1))/2+i-j+1);
					return;
				}
			}
		}
		System.out.print(n+(n*(n-1))/2+2);    //如果n没有在前44724行出现过,那么必然在第二列出现
	}
}

九、试题I:双向排序

时间限制: 5.0s 内存限制: 512.0MB 本题总分:25 分

【问题描述】

    给定序列 (a1, a2, · · · , an) = (1, 2, · · · , n),即 ai = i。

    小蓝将对这个序列进行 m 次操作,每次可能是将 a1, a2, · · · , aqi 降序排列,或者将 aqi , aqi+1, · · · , an 升序排列。

    请求出操作完成后的序列。

【输入格式】

    输入的第一行包含两个整数 n, m,分别表示序列的长度和操作次数。

    接下来 m 行描述对序列的操作,其中第 i 行包含两个整数 pi , qi 表示操作类型和参数。当 pi = 0 时,表示将 a1, a2, · · · , aqi 降序排列;当 pi = 1 时,表示将 aqi , aqi+1, · · · , an 升序排列。

【输出格式】输出一行,包含 n 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。

【样例输入】

    3 3

    0 3

    1 2

    0 2

【样例输出】 3 1 2

【样例说明】

    原数列为 (1, 2, 3)。

    第 1 步后为 (3, 2, 1)。

    第 2 步后为 (3, 1, 2)。

    第 3 步后为 (3, 1, 2)。与第 2 步操作后相同,因为前两个数已经是降序了。

【评测用例规模与约定】

    对于 30% 的评测用例,n, m ≤ 1000;

    对于 60% 的评测用例,n, m ≤ 5000;

    对于所有评测用例,1 ≤ n, m ≤ 100000,0 ≤ ai ≤ 1,1 ≤ bi ≤ n。
import java.util.Arrays;
import java.util.Scanner;
public class Main {	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt(),m=sc.nextInt();
		int[] a=new int[n];
		for(int i=0;i<n;i++){
			a[i]=i+1;
		}
		for(int i=0;i<m;i++){
			int pi=sc.nextInt();   //0 ,1-qi降序       1 ,qi-n升序
			int qi=sc.nextInt();   
			if(pi==1){
				Arrays.sort(a, qi-1, n);   //sort排序下标是【a,b)左闭右开
			}else if(pi==0){
				Arrays.sort(a,0,qi);
				for(int j=0;j<qi/2;j++){
					int tem=a[qi-1-j];
					a[qi-1-j]=a[j];
					a[j]=tem;
				}
			}			
		}
		for(int x:a){
			System.out.print(x+" ");
		}
	}
}


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {		
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt(),m=sc.nextInt();
		int[] a=new int[n];
		for(int i=0;i<n;i++){
			a[i]=i+1;
		}
		while(m>0){
			m--;
			int pi=sc.nextInt(),qi=sc.nextInt();
			
			if(pi==0){
				des(a,0,qi-1,0);
			}else{
				des(a,qi-1,n-1,1);
			}
		}
		for(int kk:a){
			System.out.print(kk+" ");
		}
	}	
	public static void des(int array[],int begin,int end,int tt){
		int max = Integer.MIN_VALUE;
	     
	     for(int i=begin;i<=end;i++){
	    	 if (array[i] > max){    //找最大值
	             max = array[i] ;
	         }
	     }

	     int[] hashArray = new int[max + 1]; //定义哈希数组
	     for (int i = 0; i < hashArray.length; ++i){
	         hashArray[i] = 0;              //为哈希数组赋初值0
	     }

	     
	     for(int i=begin;i<=end;i++){
	    	 ++hashArray[array[i]];
	     }
	     int index = begin;
	     if(tt==1){
	    	 for (int i = 0; i <hashArray.length; i++){
		         for (int j = 0; j < hashArray[i]; ++j){
		             array[index++] = i;
		         }
		     }
	     }else{
	    	 for (int i = hashArray.length-1; i >=0; i--){
	         for (int j = 0; j < hashArray[i]; ++j){
	             array[index++] = i;
	         }
	     }
	     }	     
	}	
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值