一、跳高
难度:一颗星
题目描述:
在新的一年,牛牛想跳得更高。牛牛本身可以跳高 h h h米。同时牛牛有 n n n颗跳高弹,使用第 i i i 颗跳高弹可以使牛牛跳高高度增加 a i a_i ai米,且跳高弹的效果是可以叠加的,也就是说如果牛牛使用多颗跳高弹,那么他的跳高高度将会增加这些跳高弹单个效果的和。
每颗跳高弹只能使用一次。
请问牛牛最少需要使用多少个跳高弹,才能让牛牛的高度至少是 u u u米高呢?
数据保证答案存在。
输出描述:
输出一个整数,表示答案。
示例:
输入
3 2 5
1 3 2
输出
1
说明:
只需要使用第2颗跳高弹就可以到达5米。
题解:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
int h = sc.nextInt();
int u = sc.nextInt();
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
}
if(u <= h){
System.out.println(0);
return;
}
Arrays.sort(nums);
int count = 0;
for (int i = n-1; i >= 0; i--) {
h = h+nums[i];
count++;
if (h >= u){
System.out.println(count);
return;
}
}
System.out.println(-1);
}
}
二、切绳子
难度:一颗星
题目描述:
牛牛有一条长度为
n
n
n的绳子。
第一天,绳子的长度为
n
n
n。
第二天,这条绳子会被切成两段长度分别为
⌊
n
2
⌋
\left \lfloor \frac{n}{2} \right \rfloor
⌊2n⌋,
n
−
⌊
n
2
⌋
n-\left \lfloor \frac{n}{2} \right \rfloor
n−⌊2n⌋。
第三天,对于第二天切出来的每段长度大于
1
1
1的绳子,设其长度为
m
m
m,牛牛又会将其切成
⌊
m
2
⌋
\left \lfloor \frac{m}{2} \right \rfloor
⌊2m⌋,
m
−
⌊
m
2
⌋
m-\left \lfloor \frac{m}{2} \right \rfloor
m−⌊2m⌋。
如此反复切下去… …
但是,牛牛知道,终有一天所有的绳子都会被切成长度为{1}1的绳子,到时候他就没有绳子可切了。所有绳子都变成长度为{1}1的绳子是第几天?
注:
⌊
n
2
⌋
\left \lfloor \frac{n}{2} \right \rfloor
⌊2n⌋表示
n
n
n除以
2
2
2向下取整
输入描述:
输入包含
T
T
T组数据,第一行一个整数
T
T
T。
接下来
T
T
T行每行一个正整数
n
n
n。
输出描述:
输出
T
T
T行,第
i
i
i行为第
i
i
i组数据的答案。
示例:
输入
3
1
2
3
输出
1
2
3
备注:
1
≤
n
≤
1
e
18
,
1
≤
T
≤
10000
1≤n≤1e18,1≤T≤10000
1≤n≤1e18,1≤T≤10000
题解:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
long[] nums = new long[T];
for (int i = 0; i < T; i++) {
nums[i] = sc.nextLong();
}
for (long n : nums) {
deal(n);
}
return;
}
public static void deal(long n){
int i = 1;
while (n > 1){
i++;
// n = (int)Math.max(Math.floor(n/2),n - Math.floor(n/2));
n = Math.max(n / 2, n - n / 2);
}
System.out.println(i);
}
}
三、做任务
难度:三颗星
题目描述:
假设我们有一些任务列表,任务编号从1开始。不同的任务难度也不一样,分为1-5级。
我们打算把这些任务分配给牛牛,可是牛牛比较懒,每次他接受到一个任务后,他都会从自己的todo list里找到“难度各不相同且编号和最大的五个任务”,然后再一起完成,否则的话,牛牛就把任务放到自己的todo list,什么也不做。
请你根据输入的任务列表的情况,给出牛牛完成任务的情况。
输入描述:
第一行输入一个整数n 表示任务数目。
第二行n个以空格分隔的整数,表示不同的任务难度。
1
≤
n
≤
1
0
5
1\leq n \leq 10^{5}
1≤n≤105
输出描述:
输出
m
a
t
h
i
t
(
n
)
mathit(n)
mathit(n)行,表示牛牛每次收到任务后的完成任务情况。如果牛牛什么也没做,就输出-1,否则的话,输出5个整数,分别表示牛牛完成难度为
1
,
2
,
3
,
4
,
5
\text 1,2,3,4,5
1,2,3,4,5的五个任务编号。
示例:
输入
10
1 1 2 2 3 3 4 5 4 5
输出
-1
-1
-1
-1
-1
-1
-1
2 4 6 7 8
-1
1 3 5 9 10
说明:
输出10行,牛牛只有收到第8个和第10个任务的时候,才会完成任务。
题解:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
TreeMap<Integer,Queue<Integer>> map = new TreeMap<>();
for(int i = 0;i < n;i++){
int m = sc.nextInt();
if(!map.containsKey(m)){
map.put(m, new PriorityQueue<>(Comparator.reverseOrder()));
}
map.get(m).add(i+1);
if(map.size() < 5){
System.out.println(-1);
}else{
Iterator iterator = map.keySet().iterator();
while(iterator.hasNext()){
int key = (int)iterator.next();
System.out.print(map.get(key).poll()+" ");
if(map.get(key).isEmpty()){
iterator.remove();
}
}
System.out.println();
}
}
}
}
四、换队伍
难度:三颗星
题目描述:
在一个超市里有两个收银台,现在它们面前排了长长的队伍。
第一个收银台前排了
n
1
\mathit n_{1}
n1个人,从靠近收银台开始分别编号
1
,
2
,
.
.
.
,
n
1
1
,
2
,
.
.
.
,
n
1
\text 1,2,...,n_{1}1,2,...,n 1
1,2,...,n11,2,...,n1。
第二个收银台前排了
n
2
\mathit n_{2}
n2个人,从靠近收银台开始分别编号
n
1
+
1
,
n
1
+
2
,
.
.
.
,
n
1
+
n
2
n_{1}+1,n_{1}+2,...,n_{1}+n_{2}
n1+1,n1+2,...,n1+n2 。
可是总有一些人觉的自己的队伍排的太慢了,会从自己的队伍里离开,然后排在另一个队伍的最后。
那当所有的人都换完队伍后,这两个队伍的编号最后是什么样的呢?
输入描述:
第一行三个以空格分隔的整数
n
1
,
n
2
,
q
\mathit n_{1},n_{2},q
n1,n2,q。
第二行\mathit qq个以空格分隔的整数,表示离开队伍的编号。
1
≤
n
1
,
n
2
,
q
≤
1
0
5
1\leq n_{1},n_{2},q \leq 10^{5}
1≤n1,n2,q≤105
保证离开队伍的人员编号在
[
1
,
n
1
+
n
2
]
\text [1,n1+n2]
[1,n1+n2]范围内。
输出描述:
共两行整数,分别描述两个队伍的样子,按照离收银台近的位置开始依次给出人员的编号(以空格分隔)。
保证最后两个队伍均至少有一个人。
示例:
输入
3 3 3
2 3 4
输出
1 4
5 6 2 3
说明:
初始时两个队伍的样子为:
1 2 3
4 5 6
当编号为2的人换队伍后,两个队伍的样子为:
1 3
4 5 6 2
接下来当编号为3的人换队伍后,两个队伍的样子为:
1
4 5 6 2 3
接下来当编号为4的人换队伍后,两个队伍的样子为:
1 4
5 6 2 3
题解:
import java.util.*;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n1 = sc.nextInt();
int n2 = sc.nextInt();
int q = sc.nextInt();
LinkedList<Integer> q1 = new LinkedList<>();
HashSet<Integer> set1 = new HashSet<>();
LinkedList<Integer> q2 = new LinkedList<>();
HashSet<Integer> set2 = new HashSet<>();
//给每个队伍分配序号
for(int i = 0; i < n1 + n2;i++){
if(i < n1){
q1.add(i+1);
set1.add(i+1);
}else{
q2.add(i+1);
set2.add(i+1);
}
}
//换队伍
for(int i = 0;i < q;i++){
int num = sc.nextInt();
//判断是否在队伍中
if(set1.contains(num)){
//在队伍1中,移除,排到队伍2后面
set1.remove(num);
set2.add(num);
q2.addLast(num);
}else{
set2.remove(num);
set1.add(num);
q1.addLast(num);
}
}
//重组
LinkedList<Integer> res1 = new LinkedList<>();
while (q1.size() > 0 && set1.size() > 0){
Integer num = q1.removeLast();
if (set1.contains(num)){
res1.addFirst(num);
set1.remove(num);
}
}
LinkedList<Integer> res2 = new LinkedList<>();
while (q2.size() > 0 && set2.size() > 0){
Integer num = q2.removeLast();
if (set2.contains(num)){
res2.addFirst(num);
set2.remove(num);
}
}
//输出
Iterator<Integer> iterator1 = res1.iterator();
while (iterator1.hasNext()){
System.out.print(iterator1.next()+" ");
}
System.out.println();
Iterator<Integer> iterator2 = res2.iterator();
while (iterator2.hasNext()){
System.out.print(iterator2.next()+" ");
}
System.out.println();
}
}