目录
#F 时间显示
时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分
问题描述
小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 1970 年 1 月 1 日 00 : 00 : 00 到当前时刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
输入格式
输入一行包含一个整数,表示时间。
输出格式
输出时分秒表示的当前时间,格式形如 H H :M M :S S ,其中 H H 表示时,值为 0到 23 ,M M 表示分,值为 0 到 59 ,S S 表示秒,值为 0 到 59 。时、分、秒不足两位时补前导 0 。
import java.util.Scanner;
public class questionF {
// #F 时间显示
public static void main(String[] args) {
// 根据毫秒换算时分秒
Scanner sc=new Scanner(System.in);
long t = sc.nextLong();
System.out.printf("%02d:%02d:%02d",t/3600000%24,t/60000%60,t/1000%60);
}
}
#G 最少砝码
时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分
问题描述
你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意小于等于 N 的正整数重量。
那么这套砝码最少需要包含多少个砝码?
注意砝码可以放在天平两边。
输入格式
输入包含一个正整数 N 。
输出格式
输出一个整数代表答案。
import java.util.Scanner;
public class questionG {
// #G 最少砝码
public static void main(String[] args) {
// 根据规律来找到其中的解法
Scanner sc=new Scanner(System.in);
long x=sc.nextLong();
long sum=1,cur=1;
while(sum<x){
sum+=Math.pow(3, cur);
cur++;
}
System.out.println(cur);
}
}
#H 杨辉三角形
时间限制: 5.0s 内存限制: 512.0MB 本题总分:20 分
下面的图形是著名的杨辉三角形:
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, …
给定一个正整数 N ,请你输出数列中第一次出现 N 是在第几个数?
输入格式
输入一个整数 N 。
输出格式
输出一个整数代表答案。
import java.util.Scanner;
public class questionH {
// #H 杨辉三角形
static int N;
public static void main(String[] args) {
// 根据每层的规律来找出其中的解法
Scanner sc=new Scanner(System.in);
N = new Scanner(System.in).nextInt();
if (N == 1) System.out.println(1);
else {
long ans = (N + 1L) * N / 2 + 2;
for (int m = 2; m < 16; m++) {
int start = m * 2, end = N;
while (start <= end) {
int mid = start + end >> 1;
if (C(mid, m) == N) {
ans = min(ans, (mid + 1L) * mid / 2 + m + 1);
break;
} if (C(mid, m) > N) end = mid - 1;
else start = mid + 1;
}
}
System.out.println(ans);
}
}
public static long min(long a, long b) {
return a < b ? a : b;
}
public static long C(int n, int m) {
long num = 1;
for (int nm = 1; nm <= m; n--, nm++)
if ((num = num * n / nm) > N) return num;
return num;
}
}
#I 左孩子右兄弟
时间限制: 2.0 s 内存限制: 512.0MB 本题总分:25 分
问题描述
对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树。
如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。
给定一棵包含 N 个结点的多叉树,结点从 1 至 N 编号,其中 1 号结点是根,每个结点的父结点的编号比自己的编号小。请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。注:只有根结点这一个结点的树高度为 0 。
例如如下的多叉树:
可能有以下 3 种 (这里只列出 3 种,并不是全部) 不同的 “左孩子右兄弟”表示:
其中最后一种高度最高,为 4 。
输入格式
输入的第一行包含一个整数 N 。
以下 N − 1 行,每行包含一个整数,依次表示 2 至 N 号结点的父结点编号。
输出格式
输出一个整数表示答案。
import java.io.*;
import java.util.*;
public class questionI {
//#I 左孩子右兄弟
public static List<Integer>[] tree;
public static void main(String[] args) {
// 依据题目得出状态转移方程:
// dp(v)=count(son(v))+max{dp(son(v))}
Scanner in = new Scanner(System.in);
int n = in.nextInt(), v;
tree = new List[n + 1];
for (int w = 2; w <= n; w++) {
v = in.nextInt();
if (tree[v] == null)
tree[v] = new ArrayList();
tree[v].add(w);
}
System.out.println(dp(1));
}
public static int dp(int v) {
if (tree[v] == null) return 0;
int max = 0;
for (int w : tree[v])
max = Math.max(max, dp(w));
return tree[v].size() + max;
}
public class InputReader {
BufferedReader reader;
StringTokenizer token;
public InputReader(InputStream in) {
this.reader = new BufferedReader(new InputStreamReader(in));
}
public String read() {
while (token == null || !token.hasMoreTokens()) {
try {
token = new StringTokenizer(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return token.nextToken();
}
public int readInt() {
return Integer.parseInt(read());
}
}
}
#J 双向排序
时间限制: 5.0 s 内存限制: 512.0 MB 本题总分:25 分
问题描述
给定序列 ( a 1 , a 2 , …… , a n ) = ( 1 , 2 , …… , n ) ,即 a i = i 。
小蓝将对这个序列进行 m 次操作,每次可能是将 a 1 , a 2 , …… , a qi 降序排列,或者将 a qi , a qi + 1 , …… , a n 升序排列。
请求出操作完成后的序列。
输入格式
输入的第一行包含两个整数 n , m ,分别表示序列的长度和操作次数。
接下来 m 行描述对序列的操作,其中第 i 行包含两个整数 p i , q i 表示操作类型和参数。当 p i = 0 时,表示将a 1 , a 2 , …… , a qi 降序排列;当 p i = 1 时,表示将 a qi , a qi + 1 , …… , a n 升序排列。
输出格式
输出一行,包含 n 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。
import java.io.*;
import java.util.*;
public class questionJ {
// #J 双向排序
public static void main(String[] args) {
// 对于连续且 pi相同操作
//在 pi=0 时只需要做 qi最大的操作
//在 pi=1时只需要做 qi最小的操作
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);
int n = in.readInt(), m = in.readInt();
Deque<Step> deque = new ArrayDeque();
deque.push(new Step(1, 1));
while (m-- > 0) {
int p = in.readInt();
int q = in.readInt();
while (deque.size() > 0 && deque.peek().p == p)
if (p == 0)
q = max(q, deque.pop().q);
else
q = min(q, deque.pop().q);
deque.push(new Step(p, q));
}
Integer[] ans = new Integer[n];
for (int i = 0; i < n; i++)
ans[i] = i + 1;
deque.pollLast();
while (deque.size() > 0) {
Step step = deque.pollLast();
if (step.p == 0)
Arrays.sort(ans, 0, step.q, (a, b)->(b - a));
else
Arrays.sort(ans, step.q - 1, n);
}
for (int i = 0; i < n; i++) {
out.print(ans[i]);
out.print(' ');
}
out.flush();
}
public static int max(int a, int b) {
return a > b ? a : b;
}
public static int min(int a, int b) {
return a < b ? a : b;
}
public static class Step {
public int p, q;
public Step(int p, int q) {
this.p = p;
this.q = q;
}
}
public static class InputReader {
BufferedReader reader;
StringTokenizer token;
public InputReader(InputStream in) {
this.reader = new BufferedReader(new InputStreamReader(in));
}
public String read() {
while (token == null || !token.hasMoreTokens()) {
try {
token = new StringTokenizer(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return token.nextToken();
}
public int readInt() {
return Integer.parseInt(read());
}
}
}