试题A: ASC
ASCII:A——65
ASCII:L——76
试题B:卡片
其实我们随便推导一下就知道,第一个元素不够的肯定是1,(0,2,3等)元素肯定是有多的,因为1消耗的优先级最高。
本题思路就是通过 取余 和 除10 两个步骤对一个数字进行逐步拆解
例子:131 ①先取余131%10 = 1; one--; 131/10 = 13;
②13%10 = 3;one不变; 13/10 = 1;
③1%10 = 1 ; one-- ; 1/10 = 0;跳出while循环,操作下一个数字
public static void main(String[] args) {
//one表示1还剩余多少卡片
int one = 2021;
//temp用来保存当前数字i的值
int temp = 0;
int ans = 0;
for (int i = 1;one>0; i++) {
temp = i;
while(temp != 0){
//通过取余运算来获得temp最后一个数字是不是1,是1就对卡片one--
if(temp%10 == 1){
one--;
}
//取余后相当于3位数(121)->(12),直到3位数字全部消耗完
temp = temp/10;
}
//ans用来保存当前的数字
ans = i;
System.out.println(hhh);
}
试题C:直线
我们只需要保存 两个点之间函数:y=kx+b中,k和b即可,如果k,b相同,则这个线不计入结果
public class Main{
static List<String> list = new ArrayList<>();
//最小公约数
static int gcd(int a,int b) {
if(b==0) return a;
return gcd(b,a%b);
}
public static void main(String[] args) {
for(int x1 = 0; x1 < 20; x1++) {
for(int y1 = 0; y1 < 21; y1++) {
for(int x2 = 0; x2 < 20; x2++) {
for(int y2 = 0; y2 < 21; y2++) {
if(x1 != x2) {
//可以理解我们保存的是 String版本的 k 和 b
String str = "";//存储k和b
int y = y2 - y1;
int x = x2 - x1;
int g = gcd(y,x);//求两个数的最小公因数,记录最简分数
//k = (y2 - y1) / (x2 - x1); 如果y=8,x=4 => y/g=2 x/g = 1 => k=2/1
str = y / g + "/" + x / g;
//b =( y * (x2 - x1) - x * (y2 - y1)) / (x2 - x1)
int b = y1 * x - x1 * y;
int g1 = gcd(b, x);
str = str +"&"+ b / g1 + "/" + x / g1;
list.add(str);
}
}
}
}
}
long ans = 0;
Map<String, Integer> map = new HashMap<>();
for(int i = 0; i < list.size(); i++) {
//遍历每个List保存的函数,如果kb相同,那么这个线就已经存在了
if(!map.containsKey(list.get(i))) {
ans++;
map.put(list.get(i), 1);
}
}
//这里是因为4层for循环里面,没有计算所有k=0(x1 = x2)的情况,故加上20个竖线
System.out.println(ans+20);
}
}
试题D:货物摆放
此题是全排列
非常简单,我们用hashset保存2021041820210418的所有因子
因子:2*2=4,1*4=4; 1,2,4就是4的因子
3层for循环从因子数组中,找出所有arr[i]*arr[j]*arr[k] == 2021041820210418的情况,每一个情况都是一种货物摆放的方法
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int ans = 0;
//用一个HashSet保存所有的因子————因子:2*2=4,1*4=4; 1,2,4就是4的因子
Set<Long> all = new HashSet<>();
long num= 2021041820210418L;
//此处用over保存了num的开平方的值,刚好他也能开平方,开平方后得到的答案不会改变的
Long over = (long)Math.sqrt(num);
//找到目标数字因子
for (long i = 1; i <= over; i++) {
//如果i是因子,就表示num可以整除i没有余数
if(num%i == 0){
//此时HashSet就可以加入i和num/i
all.add(i);
all.add(num/i);
}
}
//把HashSet转化成数组,数组保存的是Long类型
Long[] arrs = all.toArray(new Long[0]);
for (int i = 0; i < arrs.length; i++) {
for (int j = 0; j < arrs.length; j++) {
for (int k = 0; k < arrs.length; k++) {
//判断3个因子相乘等于num就表示一种堆叠的类型
if(arrs[i]*arrs[j]*arrs[k] == num){
ans++;
}
}
}
}
System.out.println(ans);
scan.close();
}
}
试题F:路径
此题利用了①俩点间最小公倍数求法②Floyd算法求联通路径(可以换成迪杰斯特拉更好)
思路:找到俩点间最小距离利用Floyd算法判断;
如果俩点间绝对值相减大于21,那么通过我们定义的一个Max表示距离无限大来表示;
import java.util.*;
public class Main{
//1.如果前面的数是他的因子,那么权值就会很小
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
//Max用于表示两个点直接无连接
long Max = 999999999;
//arr保存了所有点之间的路径大小
long[][] arr = new long[2021][2021];
for (int i = 0; i < 2021; i++) {
for (int j = 0; j < 2021 ; j++) {
//如果两个点超过了21,那么就设置俩点无限长
if(Math.abs(i-j)>21){
arr[i][j] = Max;
}else if(i != j){
arr[i][j] = gbs(i+1,j+1); //俩点不相等,保存俩点的距离——最小公倍数
}else {
arr[i][j] = 1;
}
}
}
//Floyd算法,判断:俩点间多了一个第三者,通过第三者能不能让俩点距离更近,如果可以就通过第三者联系二点
for (int i = 0; i < 2021; i++) {
for (int j = 0; j < 2021; j++) {
for (int k = 0; k < 2021; k++) {
if(arr[i][j]>arr[i][k]+arr[k][j]){
arr[i][j] = arr[i][k]+arr[k][j];
}
}
}
}
System.out.println(arr[0][2020]);
scan.close();
}
//利用最大公因数,求最小公倍数
public static long gbs(long a,long b){
long gb = pcb(a,b);
gb = (a/gb) * (b/gb) *gb;
return gb;
}
//求最大公因数
public static long pcb(long a,long b){
if(b == 0) return a;
return pcb(b,a%b);
}
}
试题F:时间显示
非常简单,关键在于怎么准确表达出①1天内剩余的时间 ②剩余的秒数 ③剩余的分钟数 ④剩余的小时数
import java.util.*;
public class Main{
//1.如果前面的数是他的因子,那么权值就会很小
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
long total = scan.nextLong();
int day = 24*60*60; //一天day秒
//all为一天以内的时间
int all = (int)(total/1000)%day;
//秒:SS -> all%60 可以得到秒的余数
long SS = all%60;
//分:MM -> all/60=总分钟数 all/60%60分钟数余数
long MM = all/60%60;
//时:HH -> all/3600=总小时数 all/3600%24小时数余数
long HH = all/3600%24;
String S = ""+SS;
String M = ""+MM;
String H = ""+HH;
//SS,MM,HH如果小于10,直接输出就会只有一个数,应该在前面加个0凑足两位数
if(SS < 10) S = "0"+SS;
if(MM < 10) M = "0"+MM;
if(HH<10) H = "0"+HH;
System.out.println(H+":"+M+":"+S);
scan.close();
}
}