第一题
标题:三角形面积
已知三角形三个顶点在直角坐标系下的坐标分别为:
(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-8
public 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,则返回false
for(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返回为true
if(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 12233 01234 56789
以下摆放不满足要求:
11122 11122 33311 111111 122221 122221 111111 11122 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的部件,则返回false
if(i<x1||i>x2||j<y1||j>y2)
{
if(a[i][j]==b)
return false;
}
//如果在矩形内部存在不等于b的部件,则返回false
else
{
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");
else
System.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;
//用递归求map
public 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效率优于Scanner
BufferedReader 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);
}
//递归求map
dfs(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");
else
System.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 13 000 【样例输出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;
}
@Override
public int compareTo(A o) {
// TODO Auto-generated method stub
if(o.value-value==0)
return id-o.id;
else
return o.value-value;
}
}
static class B implements Comparable<B>
{
int id;
int value;
B(int a,int b)
{
id=a;value=b;
}
@Override
public int compareTo(B o) {
// TODO Auto-generated method stub
if(o.value-value==0)
return id-o.id;
else
return 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')//只有一个1
System.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')//只有一个0
System.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");
}
}