2018年第九届蓝桥杯Java本科B组国赛题解
第一题
标题:三角形面积
已知三角形三个顶点在直角坐标系下的坐标分别为:
(2.3, 2.5)
(6.4, 3.1)
(5.1, 7.2)
求该三角形的面积。
注意,要提交的是一个小数形式表示的浮点数。
要求精确到小数后3位,如不足3位,需要补零。
代码
或者使用 海伦公式 p=(a+b+c)/2,S=Math.sqrt(p* (p-a)* (p-b)*(p-c))
import java.io.*;
import java.util.*;
/*
A(2.3, 2.5)
B(6.4, 3.1)
C(5.1, 7.2)*/
public class Main
{public static void main(String[] args){double a=Math.sqrt((5.1-6.4)*(5.1-6.4)+(7.2-3.1)*(7.2-3.1));double b=Math.sqrt((5.1-2.3)*(5.1-2.3)+(7.2-2.5)*(7.2-2.5));double c=Math.sqrt((6.4-2.3)*(6.4-2.3)+(3.1-2.5)*(3.1-2.5));double p=(a+b+c)/2;double result=Math.sqrt(p*(p-a)*(p-b)*(p-c));System.out.println(result);}
}
结果:8.795
第二题
标题:最大乘积
把 1~9 这9个数字分成两组,中间插入乘号,
有的时候,它们的乘积也只包含1~9这9个数字,而且每个数字只出现1次。
比如:
984672 * 351 = 345619872
98751 * 3462 = 341875962
9 * 87146325 = 784316925
…
符合这种规律的算式还有很多,请你计算在所有这些算式中,乘积最大是多少?
注意,需要提交的是一个整数,表示那个最大的积,不要填写任何多余的内容。
(只提交乘积,不要提交整个算式)
代码
import java.io.*;
import java.util.*;public class Main
{public static int[] a=new int[9];//0-8public static int[] vis=new int[10];public static int[] test;public static long maxn=0;public static void main(String[] args){vis[0]=1;dfs(0);System.out.println(maxn);}//判断乘积是否为1-9各个数只出现一次public static boolean judge(long result){//test数组存储每个数出现的次数test=new int[10];while(result>0){test[(int) (result%10)]++;result/=10;}//遍历test数组,如果存在某个数出现次数不为1,则返回falsefor(int i=1;i<=9;i++){if(test[i]!=1){return false;}}return true; }public static void dfs(int index){if(index==9){long result;//遍历分割点for(int k=0;k<9;k++){int num1=0,num2=0;//第一个乘数for(int i=0;i<=k;i++){num1=num1*10+a[i];}//第二个乘数for(int i=k+1;i<9;i++){num2=num2*10+a[i];}//获得乘积result=num1*num2;//如果乘积大于maxn,乘积位数为9位,且judge返回为trueif(result>maxn&&String.valueOf(result).length()==9&&judge(result)) {maxn=result;}}}//组成一个个各位数不同的9位数for(int i=9;i>0;i--){if(vis[i]==0){vis[i]=1;a[index]=i;dfs(index+1);vis[i]=0;}}}
}
结果:839542176
第三题
标题:全排列
对于某个串,比如:“1234”,求它的所有全排列。
并且要求这些全排列一定要按照字母的升序排列。
对于“1234”,应该输出(一共4!=24行):
1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321
下面是实现程序,请仔细分析程序逻辑,并填写划线部分缺少的代码。import java.util.*; public class A {static void permu(char[] data, int cur){if(cur==data.length-1){System.out.println(new String(data));return;}for(int i=cur; i<data.length; i++){char tmp = data[i]; for(int j=i-1; j>=cur; j--) data[j+1] = data[j];data[cur] = tmp; permu(data, cur+1); tmp = data[cur]; __________________________________________ ;data[i] = tmp; }}static void permu(String x){permu(x.toCharArray(),0);}public static void main(String[] args){permu("1234");} }
填空结果:for(int j=cur;j<i;j++) data[j]=data[j+1]
有其他答案也符合题目要求,但感觉这个答案是比较准确的,仔细观察代码中的这几行,你就可以看出来
char tmp = data[i];
for(int j=i-1; j>=cur; j--) data[j+1] = data[j];
data[cur] = tmp;
tmp = data[cur];
for(int j=cur; j<i; j++) data[j]=data[j+1];
data[i] = tmp;
输出结果:
第四题
标题:整理玩具
小明有一套玩具,一共包含NxM个部件。这些部件摆放在一个包含NxM个小格子的玩具盒中,每个小格子中恰好摆放一个部件。
每一个部件上标记有一个0~9的整数,有可能有多个部件标记相同的整数。
小明对玩具的摆放有特殊的要求:标记相同整数的部件必须摆在一起,组成一个矩形形状。
如以下摆放是满足要求的:00022 00033 44444 12244 12244 1223301234 56789
以下摆放不满足要求:
11122 11122 33311111111 122221 122221 11111111122 11113 33333
给出一种摆放方式,请你判断是否符合小明的要求。
输入
输入包含多组数据。
第一行包含一个整数T,代表数据组数。 (1 <= T <= 10)
以下包含T组数据。
每组数据第一行包含两个整数N和M。 (1 <= N, M <= 10)
以下包含N行M列的矩阵,代表摆放方式。
输出
对于每组数据,输出YES或者NO代表是否符合小明的要求。
【样例输入】
3
3 5
00022
00033
44444
3 5
11122
11122
33311
2 5
01234
56789
【样例输出】
YES
NO
YES
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
代码
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;public class Main {public static boolean show(int[][] a,Set<Integer> set){boolean result=true;Iterator<Integer> it=set.iterator();//依次获得每种部件编号的矩形区域while(it.hasNext()){ int x1=0,x2=0,y1=0,y2=0;//起点(x1,y1),终点(x2,y2)int t=it.next();//每种部件编号int flag=0;//定义一个变量,判断是否是第一次出现for(int i=0;i<a.length;i++)for(int j=0;j<a[0].length;j++){//第一次出现该编号if(a[i][j]==t&&flag==0){x1=i;y1=j;x2=x1;y2=y1;flag=1;}//不是第一次出现,只需要改变终点else if(a[i][j]==t&&flag==1){x2=i;y2=j;}}//判断该编号的矩形区域是否符合条件if(!judge(a,x1,y1,x2,y2,t)){result=false;break;} }return result;}//判断是否符合条件public static boolean judge(int[][] a,int x1,int y1,int x2,int y2,int b){for(int i=x1;i<a.length;i++)for(int j=y1;j<a[0].length;j++){//如果在矩形范围外还存在等于b的部件,则返回falseif(i<x1||i>x2||j<y1||j>y2){if(a[i][j]==b)return false;}//如果在矩形内部存在不等于b的部件,则返回falseelse{if(a[i][j]!=b)return false;}}return true;}public static void main(String[] args){Scanner scan = new Scanner(System.in);int t=scan.nextInt();while(t>0){int n=scan.nextInt();int m=scan.nextInt();int[][] a=new int[n][m];//用set存储矩阵中出现的数字种类数Set<Integer> set=new HashSet<>();for(int i=0;i<n;i++){String s=scan.next();for(int j=0;j<m;j++){//a存储二维矩阵a[i][j]=s.toCharArray()[j]-'0';set.add(a[i][j]);//种类数}}boolean result=show(a,set);if(result==true)System.out.println("YES");elseSystem.out.println("NO");set.clear();t--;}scan.close();}
}
第五题
标题:版本分支
小明负责维护公司一个奇怪的项目。这个项目的代码一直在不断分支(branch)但是从未发生过合并(merge)。
现在这个项目的代码一共有N个版本,编号1~N,其中1号版本是最初的版本。
除了1号版本之外,其他版本的代码都恰好有一个直接的父版本;即这N个版本形成了一棵以1为根的树形结构。
如下图就是一个可能的版本树:1/ \2 3| / \5 4 6
现在小明需要经常检查版本x是不是版本y的祖先版本。你能帮助小明吗?
输入
第一行包含两个整数N和Q,代表版本总数和查询总数。
以下N-1行,每行包含2个整数u和v,代表版本u是版本v的直接父版本。
再之后Q行,每行包含2个整数x和y,代表询问版本x是不是版本y的祖先版本。
对于30%的数据,1 <= N <= 1000 1 <= Q <= 1000
对于100%的数据,1 <= N <= 100000 1 <= Q <= 100000
输出
对于每个询问,输出YES或NO代表x是否是y的祖先。
【样例输入】
6 5
1 2
1 3
2 5
3 6
3 4
1 1
1 4
2 6
5 2
6 4
【样例输出】
YES
YES
NO
NO
NO
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
代码
import java.io.*;
import java.util.*;
/*
因为刚做完2017年国赛题,看到这道题联想到了17年的第三题树形显示*/
public class Main {public static Map<Integer,List<Integer>> map;//用递归求mappublic static void dfs(int index){//获取该节点的直接孩子节点List<Integer> fin=map.get(index);//对于每个孩子节点,递归求其孩子节点for(int i=0;i<fin.size();i++){//如果map中包含该孩子节点if(map.containsKey(fin.get(i))){//将该孩子节点下的孩子节点添加到fin中fin.addAll(map.get(fin.get(i)));dfs(fin.get(i));}}}public static void main(String[] args) throws IOException{//map键为所有的父亲节点,值为每个父亲节点拥有的全部孩子//对于样例来说,即map为 {1=[2, 3, 5, 6, 4], 2=[5], 3=[6, 4]}map=new HashMap<Integer,List<Integer>>();//使用BufferedReader效率优于ScannerBufferedReader reader=new BufferedReader(new InputStreamReader(System.in));//读取输入并存储String[] a=reader.readLine().split(" ");int N=Integer.parseInt(a[0]);int Q=Integer.parseInt(a[1]);List<Integer> list;for(int i=0;i<N-1;i++){String[] b=reader.readLine().split(" ");int u=Integer.parseInt(b[0]);int v=Integer.parseInt(b[1]);//如果该父亲节点不存在,则创建空list列表if(!map.containsKey(u)){list=new ArrayList<Integer>();}//如果存在则直接获得父亲节点对应的list列表else list=map.get(u);//添加新的孩子节点list.add(v);map.put(u, list);}//递归求mapdfs(1);//存储需判断的数据int[] x=new int[Q];int[] y=new int[Q];for(int i=0;i<Q;i++){String[] c=reader.readLine().split(" ");x[i]=Integer.parseInt(c[0]);y[i]=Integer.parseInt(c[1]);}//逐行判断for(int i=0;i<Q;i++){if(x[i]==y[i]) System.out.println("YES");else if(map.get(x[i])==null||map.get(x[i]).contains(y[i])==false)System.out.println("NO");elseSystem.out.println("YES");}}
}
附加一组测试用例:
10 6
1 2
1 3
2 4
2 5
3 6
3 7
4 8
7 9
7 10
6 5
1 4
7 9
1 10
5 8
3 4
结果:
NO
YES
YES
YES
NO
NO
第六题
标题:防御力
小明最近在玩一款游戏。对游戏中的防御力很感兴趣。
我们认为直接影响防御的参数为“防御性能”,记作d,而面板上有两个防御值A和B,与d成对数关系,A=2d,B=3d(注意任何时候上式都成立)。
在游戏过程中,可能有一些道具把防御值A增加一个值,有另一些道具把防御值B增加一个值。
现在小明身上有n1个道具增加A的值和n2个道具增加B的值,增加量已知。
现在已知第i次使用的道具是增加A还是增加B的值,但具体使用那个道具是不确定的,请找到一个字典序最小的使用道具的方式,使得最终的防御性能最大。
初始时防御性能为0,即d=0,所以A=B=1。
【输入格式】
输入的第一行包含两个数n1,n2,空格分隔。
第二行n1个数,表示增加A值的那些道具的增加量。
第三行n2个数,表示增加B值的那些道具的增加量。
第四行一个长度为n1+n2的字符串,由0和1组成,表示道具的使用顺序。0表示使用增加A值的道具,1表示使用增加B值的道具。输入数据保证恰好有n1个0,n2个1。
【输出格式】
对于每组数据,输出n1+n2+1行,前n1+n2行按顺序输出道具的使用情况,若使用增加A值的道具,输出Ax,x为道具在该类道具中的编号(从1开始)。若使用增加B值的道具则输出Bx。最后一行输出一个大写字母E。【样例输入1】 1 2 4 2 8 101 【样例输出1】 B2 A1 B1 E 【样例输入2】 3 0 7 11 13000 【样例输出2】 A1 A2 A3 E【样例说明】 对于第一组测试数据,操作过程如下: 操作 d A B 初始 0 1 1 B2 2 4 9 A1 3 8 27 B1 log3(29) 2^(log3(29)) 29
可以证明,这个值是最大的。 对于第二组测试数据,可见无论用什么顺序,A最后总为32,即d总为5,B总为243。
【数据规模】
对于20%的数据,字符串长度<=10000;
对于70%的数据,字符串长度<=200000;
对于100%的数据,字符串长度<=2000000,输入的每个增加值不超过2^30。
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
代码
import java.io.*;
import java.util.*;public class Main {static A[] a;static B[] b;//值相同按字典序排序(从小到大),否则按值从大到小排序static class A implements Comparable<A>{int id;int value;A(int a,int b){id=a;value=b;}@Overridepublic int compareTo(A o) {// TODO Auto-generated method stubif(o.value-value==0)return id-o.id;elsereturn o.value-value;}}static class B implements Comparable<B>{int id;int value;B(int a,int b){id=a;value=b;}@Overridepublic int compareTo(B o) {// TODO Auto-generated method stubif(o.value-value==0)return id-o.id;elsereturn o.value-value;}}public static void main(String[] args) throws IOException{BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));String s1=reader.readLine();int n1=Integer.parseInt(s1.split(" ")[0]);int n2=Integer.parseInt(s1.split(" ")[1]);a=new A[n1+1];b=new B[n2+1];String[] sa=reader.readLine().split(" ");String[] sb=reader.readLine().split(" ");char[] s=reader.readLine().toCharArray();for(int i=1;i<=n1;i++) {int id=i;int value=Integer.parseInt(sa[i-1]);a[i]=new A(id,value);}for(int i=1;i<=n2;i++){int id=i;int value=Integer.parseInt(sb[i-1]);b[i]=new B(id,value);}//排序Arrays.sort(a,1,n1+1);Arrays.sort(b,1,n2+1);int countA=1,countB=1;int[] temp;for(int i=0;i<n1+n2;i++){if(s[i]=='1')//当前为1{if(i+1==n1+n2||s[i+1]=='0')//只有一个1System.out.println("B"+b[countB++].id);else//出现连续个1{int k=0;int j;temp=new int[s.length-i+5];//将连续的1的id号存入temp数组中for(j=i;j<n1+n2;j++){if(s[j]!='1') break;temp[k++]=b[countB++].id;}//对temp数组按字典序从小到大排序Arrays.sort(temp,0,k);i=j-1;for(j=0;j<k;j++){System.out.println("B"+temp[j]);}}}else//当前为0{if(i+1==n1+n2||s[i+1]=='1')//只有一个0System.out.println("A"+a[countA++].id);else//出现连续个0{int k=0;int j;temp=new int[s.length-i+5];for(j=i;j<n1+n2;j++){if(s[j]!='0') break;temp[k++]=a[countA++].id;}Arrays.sort(temp,0,k);i=j-1;for(j=0;j<k;j++){System.out.println("A"+temp[j]);}}} }System.out.println("E");}
}
2018年第九届蓝桥杯Java本科B组国赛题解相关推荐
- 2018年第九届蓝桥杯C/C++ C组国赛 —— 第四题:约瑟夫环
标题:约瑟夫环 n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数. (报数是从1报起)当报到 k 的时候,这个人就退出游戏圈.下一个人重新从1开始报数. 求最 ...
- 2018年第九届蓝桥杯C/C++ C组国赛 —— 第三题:全排列
标题:全排列 对于某个串,比如:"1234",求它的所有全排列. 并且要求这些全排列一定要按照字母的升序排列. 对于"1234",应该输出(一共4!=24行): ...
- 2018年第九届蓝桥杯C/C++ C组国赛 —— 第二题:最大乘积
标题:最大乘积 把 1~9 这9个数字分成两组,中间插入乘号, 有的时候,它们的乘积也只包含1~9这9个数字,而且每个数字只出现1次. 比如: 984672 * 351 = 345619872 987 ...
- 2018年第九届蓝桥杯C/C++ C组国赛 —— 第一题:年龄问题
标题:年龄问题 s夫人一向很神秘.这会儿有人问起她的年龄,她想了想说: "20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍". 你能算出s夫人现在的年龄吗? ...
- 2018年第九届蓝桥杯C/C++ A组国赛 —— 第四题:约瑟夫环
标题:约瑟夫环 n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数. (报数是从1报起)当报到 k 的时候,这个人就退出游戏圈.下一个人重新从1开始报数. 求最 ...
- 2018年第九届蓝桥杯C/C++ A组国赛 —— 第二题:阅兵方阵
标题:阅兵方阵 x国要参加同盟阅兵活动. 主办方要求每个加盟国派出的士兵恰好能组成 2 个方阵. x国发现弱小的 y国派出了130人的队伍,他们的士兵在行进中可以变换2种队形: 130 = 81 + ...
- 第九届蓝桥杯c/c++A组省赛题解
分数 题目 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来. 类似:3 / 2 当然,这只是加了前2项而已 ...
- 【2018.10.18】noip模拟赛Day2 地球危机(2018年第九届蓝桥杯C/C++A组省赛 三体攻击)...
题目描述 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 $A × B × C$ 艘战舰,在太 空中排成一个 $A$ 层 $B$ 行 $C$ 列的立方体.其中,第 $i$ 层第 $j$ 行第 $k ...
- 2018年第九届蓝桥杯C/C++A组省赛 题面部分题解
第一题 标题:分数 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来. 类似: 3/2 当然,这只是加了前2 ...
最新文章
- 一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一...
- mysql报错:This version of MySQL doesn’t yet support ‘LIMIT IN/ALL/ANY/SOME 解决方法
- 【转】Linux root修改密码失败
- linux 知识点 随笔
- 踩坑记录--VScode编辑不同文件没有及时crtl+s,导致文件修改无效
- html中加减号怎么输入,jQuery 实现点击加减号改变input标签中的value值,该怎么解决...
- 程序员千万不要做舔狗啊!
- 阿里云API网关(18)请求报文和响应报文
- HelloDjango 第 10 篇:小细节 Markdown 文章自动生成目录,提升阅读体验
- java坦克大战 素材_坦克大战 游戏源码 素材 文档(了解面向对象的具体编程)
- 74cms v5.0.1漏洞
- WIN7 VS2005 安装wince6.0教程(不管是X86还是X64,我都尝试成功了)
- 基于myscript.js的web手写板(支持中文识别)
- 编译Linux内核4.4实现可读NTFS
- 虚拟机服务器异常怎么解决,windows server 2016 虚拟机异常关闭
- T-BOX,OBD区别
- win11右键菜单缺少“新建“选项解决办法“
- 开源物联网监控告警平台JAVA开发
- 团队内的沟通方式:网络 OR 当面
- C语言中的循环语句(while、dowhile、for)