第一题 相隔天数
输入日期格式:YYYYMMDD,求与20190205相隔的天数。
例:
输入:
20190208
输出:
3
这题用其他语言不好做,在java中使用java.util.Date以及java.util.Calendar类获取毫秒数,相减之后除以一天的毫秒数得出相隔天数。
import java.util.Calendar;
import java.util.Scanner;
public class A_2019 {
public static void main(String[] args) {
//获取输入的年月日
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
int year=Integer.parseInt(s)/10000;
int month=(Integer.parseInt(s)%10000)/100;
int day=Integer.parseInt(s)%100;
//创建两个calendar对象
//!!注意 如果不给cal的毫秒值设置为0 会引起随机误差
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.set(2019,02,05,0,0,0);
cal1.set(Calendar.MILLISECOND, 0);
cal2.set(year,month,day,0,0,0);
cal2.set(Calendar.MILLISECOND, 0);
//第一次getTime是获得date对象 第二次getTime获取毫秒值
long a=cal2.getTime().getTime()-cal1.getTime().getTime();
long b=a/(1000*3600*24);
System.out.println(b);
}
}
第二题 最大连续子序列
给定一个数字序列A1,A2…An,求i,j(1<=i<=j<=n),使得Ai+…+Aj最大,输出这个最大和。
例:
输入:
6
-2 11 -4 13 -5 -2
输出:
20
这题是非常典型的动态规划问题,dp[i]表示以Ai为结尾的最大子序列,递推公式为dp[i]=max(dp[i-1]+Ai,Ai);然后获取dp数组中的最大值输出。
import java.util.Scanner;
public class B_2019 {
public static void main(String[] args) {
//初始化
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int max;
int A[]=new int[n];
int dp[]=new int[n];
for (int i = 0; i < A.length; i++) {
A[i]= scanner.nextInt();
}
//动态规划
dp[0]=A[0];
max=A[0];
for (int i = 1; i < A.length; i++) {
dp[i]=Math.max(dp[i-1]+A[i],A[i]);
max=Math.max(max,dp[i]);
}
System.out.println(max);
}
}
第三题 有向树形态
求N个结点能够组成的二叉树的个数。
例:
输入:
3
输出:
5
这道题在我看来有点问题,N个节点组成的二叉树个数,只要形状一样就算一样吗?(这题在Acwing中,可以到网站上试试能不能AC。3691. 有向树形态 - AcWing题库)
从输出的5可以知道是指形状一样的算一个,使用动态规划来做。以总共5个节点举例,可以分成左边4个,右边0个;左边3个,右边1个;左边2个,右边2个...,所以dp的时间复杂度为o(n2).(注意遇到大数据都用long来做)
//用dp来做
import java.util.Scanner;
class Main{
static Scanner scanner=new Scanner(System.in);
public static void main(String[] args){
int n=scanner.nextInt();
long dp[]=new long[n+1];
dp[0]=1;
dp[1]=1;
int i=0,j=0;
for(i=2;i<=n;i++){
long temp=0;
for(j=0;j<i;j++){
temp+=dp[j]*dp[i-1-j];
}
dp[i]=temp;
}
System.out.println(dp[n]);
}
}