第十套
淘汰分数
题目
某比赛已经进入了淘汰赛阶段,已知共有n名选手参与了此阶段比赛,他们的得分分别是a_1,a_2….a_n,小美作为比赛的裁判希望设定一个分数线m,使得所有分数大于m的选手晋级,其他人淘汰。
但是为了保护粉丝脆弱的心脏,小美希望晋级和淘汰的人数均在[x,y]之间。
显然这个m有可能是不存在的,也有可能存在多个m,如果不存在,请你输出-1,如果存在多个,请你输出符合条件的最低的分数线。
解答
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x = sc.nextInt();
int y = sc.nextInt();
if(x < 0 || y > n){
System.out.println("-1");
}
int[] scores = new int[n];
for(int i = 0; i < n; i++){
scores[i] = sc.nextInt();
}
Arrays.sort(scores);
int low = scores[x-1];
int high = scores[y-1];
if(low <= high){
System.out.println(low);
}else{
System.out.println("-1");
}
}
}
正则序列
题目
我们称一个长度为n的序列为正则序列,当且仅当该序列是一个由1~n组成的排列,即该序列由n个正整数组成,取值在[1,n]范围,且不存在重复的数,同时正则序列不要求排序
有一天小团得到了一个长度为n的任意序列,他需要在有限次操作内,将这个序列变成一个正则序列,每次操作他可以任选序列中的一个数字,并将该数字加一或者减一。
请问他最少用多少次操作可以把这个序列变成正则序列?
代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
int count = 0;
for(int i = 0; i < n; i++){
count = count + Math.abs(arr[i]-(i+1));
}
System.out.println(count);
}
}
公司食堂
题目
小美和小团所在公司的食堂有N张餐桌,从左到右摆成一排,每张餐桌有2张餐椅供至多2人用餐,公司职员排队进入食堂用餐。小美发现职员用餐的一个规律并告诉小团:当男职员进入食堂时,他会优先选择已经坐有1人的餐桌用餐,只有当每张餐桌要么空着要么坐满2人时,他才会考虑空着的餐桌;
当女职员进入食堂时,她会优先选择未坐人的餐桌用餐,只有当每张餐桌都坐有至少1人时,她才会考虑已经坐有1人的餐桌;
无论男女,当有多张餐桌供职员选择时,他会选择最靠左的餐桌用餐。现在食堂内已有若干人在用餐,另外M个人正排队进入食堂,小团会根据小美告诉他的规律预测排队的每个人分别会坐哪张餐桌。
代码
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
int t = Integer.parseInt(reader.readLine());
for(int i = 0 ; i < t; i++){
int n = Integer.parseInt(reader.readLine());
char[] tables = reader.readLine().toCharArray();
int m = Integer.parseInt(reader.readLine());
char[] waits = reader.readLine().toCharArray();
List<PriorityQueue<Integer>> list = new ArrayList<>(2);
list.add(new PriorityQueue<Integer>());
list.add(new PriorityQueue<Integer>());
for(int j = 0; j < n; j++){
if(tables[j] != '2'){
list.get((int)tables[j]-(int)'0').add(j+1);
}
}
for(int j = 0; j < m; j++){
int index = 0;
if(waits[j] == 'M'){
if(list.get(1).isEmpty() == false){//还有1坐的位置
index = list.get(1).poll();
writer.write(index+"\n");
}else{//没有1坐了,坐空桌
index = list.get(0).poll();
writer.write(index+"\n");
list.get(1).offer(index);
}
}else{
if(list.get(0).isEmpty() == false){//还有空桌
index = list.get(0).poll();
writer.write(index+"\n");
list.get(1).offer(index);
}else{//没有空桌,坐一个座位的
index = list.get(1).poll();
writer.write(index+"\n");
}
}
writer.flush();
}
}
}
}
第九套
糕点
题目
小团的蛋糕铺长期霸占着美团APP中“蛋糕奶茶”栏目的首位,因此总会吸引各路食客前来探店。
小团一天最多可以烤n个蛋糕,每个蛋糕有一个正整数的重量。
早上,糕点铺已经做好了m个蛋糕。
现在,有一个顾客要来买两个蛋糕,他希望买这一天糕点铺烤好的最重的和最轻的蛋糕,并且希望这两个蛋糕的重量恰好为a和b。剩余的n-m个蛋糕可以现烤,请问小团能否满足他的要求?
代码
/*
总共可以做n个,已经做了m个蛋糕,k=n-m表示还需要做的蛋糕:
*/
import java.util.*;
import java.io.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str1 = null;
while((str1 = reader.readLine()) != null){
//获取a,b,m,n参数
String[] params = str1.split(" ");
int n = Integer.parseInt(params[0]);
int m = Integer.parseInt(params[1]);
int a = Integer.parseInt(params[2]);
int b = Integer.parseInt(params[3]);
if(a > b){
int temp = a;
a = b;
b = temp;
}
//计算出美味值
String[] temp = reader.readLine().split(" ");
int[] cakes = new int[m];
for(int i = 0; i < m; i++){
cakes[i] = Integer.parseInt(temp[i]);
}
Arrays.sort(cakes);
int k = n - m;//还可以做的蛋糕数量
if(n < 2){
System.out.println("NO");
}else{
if(m == 0){//一个蛋糕都没做好
if(k >= 2){//还可以至少做两个蛋糕
System.out.println("YES");
}else{
System.out.println("NO");
}
}else if(m == 1){//做好了一个蛋糕
if(cakes[0] == a || cakes[0] == b){//这个蛋糕的重量恰好等于a或者b
if(k >= 1){//还可以至少做一个蛋糕
System.out.println("YES");
}else{//一个蛋糕也做不了
System.out.println("NO");
}
}else{
if(cakes[0] < a || cakes[0] > b){//做好的哪一个比a还小或者比b大
System.out.println("NO");
}else{
if(k >= 2){//还可以至少做两个蛋糕
System.out.println("YES");
}else{//一个蛋糕也做不了
System.out.println("NO");
}
}
}
}else{
int low = cakes[0];//美味值最低的蛋糕
int high = cakes[m-1];//美味值最高的蛋糕
if(a == low && b == high){//正好都有
System.out.println("YES");
}else if(a == low){//最小的等于a
if(high > b){
System.out.println("NO");
}else{
if(k >= 1){//还可以至少做一个蛋糕
System.out.println("YES");
}else{//一个蛋糕也做不了
System.out.println("NO");
}
}
}else if(b == high){
if(low < a){
System.out.println("NO");
}else{
if(k >= 1){//还可以至少做一个蛋糕
System.out.println("YES");
}else{//一个蛋糕也做不了
System.out.println("NO");
}
}
}else{
if(low > a && high < b){//在区间内
if(k >= 2){//还可以至少做两个蛋糕
System.out.println("YES");
}else{//一个蛋糕也做不了
System.out.println("NO");
}
}else{//在区间外
System.out.println("NO");
}
}
}
}
}
}
}
晋级人数
题目
小团是某综艺节目的策划,他为某个游戏环节设计了一种晋级规则,已知在这个游戏环节中每个人最后都会得到一个分数score_i,显而易见的是,游戏很有可能出现同分的情况,小团计划该环节晋级人数为x人,则将所有人的分数从高到低排序,所有分数大于等于第x个人的分数且得分不为0的人都可以晋级。
请你求出本环节的实际晋级人数。显然这个数字可能是0,如果所有人的得分都是0,则没有人满足晋级条件。
代码
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import java.util.Scanner;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] params = reader.readLine().split(" ");
int n = Integer.parseInt(params[0]);
int x = Integer.parseInt(params[1]);
String[] temp = reader.readLine().split(" ");
Integer[] scores = new Integer[n];
for(int i = 0; i < n; i++){
scores[i] = Integer.parseInt(temp[i]);
}
Arrays.sort(scores, Collections.reverseOrder());
int rec = scores[x-1];
int count = 0;
for(int i = 0; i < n; i++){
if(scores[i] != 0 && scores[i] >= rec){
count++;
}
}
System.out.println(count);
}
}
回转寿司
题目
链接
来源:牛客网
小美请小团吃回转寿司。转盘上有N盘寿司围成一圈,第1盘与第2盘相邻,第2盘与第3盘相邻,…,第N-1盘与第N盘相邻,第N盘与第1盘相邻。小团认为第i盘寿司的美味值为A[i](可能是负值,如果小团讨厌这盘寿司)。现在,小团要在转盘上选出连续的若干盘寿司,使得这些寿司的美味值之和最大(允许不选任何寿司,此时美味值总和为0)。
代码
import java.io.*;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Integer t = Integer.parseInt(reader.readLine());
for(int i = 0; i < t; i++){
Integer n = Integer.parseInt(reader.readLine());
String[] temp = reader.readLine().split(" ");
int[] arr = new int[n];
int sum = 0;
for(int j = 0; j < n; j++){
arr[j] = Integer.parseInt(temp[j]);
sum += arr[j];
}
int maxSum = arr[0],currentMaxSum = arr[0];
int minSum = arr[0],currentMinSum = arr[0];
for(int j = 1; j < n; j++){
currentMaxSum = Math.max(arr[j],currentMaxSum+arr[j]);
maxSum = Math.max(currentMaxSum,maxSum);
currentMinSum = Math.min(arr[j],currentMinSum+arr[j]);
minSum = Math.min(currentMinSum,minSum);
}
System.out.println(Math.max(sum-minSum,maxSum));
}
}
}