以下题目附带Java解法,是我个人写的,不一定是标准答案,没有真正的测试数据,只能说是我自己认为通过率100%,也不一定是最优解。如果有错误或是有更好的解法,请评论告诉我!!!
77.满足最大消费额度
双十一众多商品进行打折销售
小明想购买自己心仪的一些物品
但由于购买资金限制
所以他决定从众多心仪商品中购买三件
而且想尽可能得花完资金
现在请你设计一个程序 计算小明尽可能花费的最大资金数
输入描述:
输入第一行为一维整型数组m
数组长度小于100
数组元素记录单个商品的价格
单个商品加个小于1000
输入第二行为购买资金的额度r
r<100000
输出描述:
输出为满足上述条件的最大花费额度
注意:如果不存在满足上述条件的商品请返回-1
示例:
输入
23,26,36,27
78
输出
76
说明:
金额23、26、27得到76而且最接近且小于输入金额78
示例:
输入
23,30,40
26
输出
-1
说明
因为输入的商品无法满足3件之和小于26
故返回-1
输入格式正确无需考虑输入错误情况4
// 满足最大消费额度
public static void test077() {
Scanner sc = new Scanner(System.in);
String line1 = sc.nextLine();
String line2 = sc.nextLine();
String[] split = line1.split(",");
int len = split.length;
int sum = 0;
// 依次遍历,列出所有的三数之和
for (int i = 0; i < len - 2; i++) {
for (int j = i + 1; j < len - 1; j++) {
for (int k = j + 1; k < len; k++) {
int res = Integer.parseInt(split[i]) + Integer.parseInt(split[j]) + Integer.parseInt(split[k]);
if (res < Integer.parseInt(line2)) {
// 与原来的值比较,留下大的值
sum = Math.max(sum, res);
}
}
}
}
if (sum == 0) {
System.out.println(-1);
} else {
System.out.println(sum);
}
}
76.小朋友身高位置
在学校中
N个小朋友站成一队
第i个小朋友的身高为height[i]
第i个小朋友可以看到第一个比自己身高更高的小朋友j
那么j是i的好朋友
(要求:j>i)
请重新生成一个列表
对应位置的输出是每个小朋友的好朋友的位置
如果没有看到好朋友
请在该位置用0代替
小朋友人数范围 0~40000
输入描述:
第一行输入N
N表示有N个小朋友
第二行输入N个小朋友的身高height[i]
都是整数
输出描述:
输出N个小朋友的好朋友的位置
示例1:
输入:
2
100 95
输出
0 0
说明
第一个小朋友身高100站在队伍末尾
向队首看 没有比他身高高的小朋友
所以输出第一个值为0
第二个小朋友站在队首前面也没有比他身高高的小朋友
所以输出第二个值为0
示例2:
输入
8
123 124 125 121 119 122 126 123
输出
1 2 6 5 5 6 0 0
说明:
123的好朋友是1位置上的124
124的好朋友是2位置上的125
125的好朋友是6位置上的126
依此类推
// 小朋友身高位置
public static void test076() {
Scanner sc = new Scanner(System.in);
// 数组长度
int len = Integer.parseInt(sc.nextLine());
String line = sc.nextLine();
String[] split = line.split(" ");
// 双层循环,依次往后比较
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (Integer.parseInt(split[i]) < Integer.parseInt(split[j])) {
System.out.print(j + " ");
break;
}
// 当看到最后一个,还没结束,说明没有,输出0
if (j == len - 1) {
System.out.print(0 + " ");
}
}
}
// 队首直接输出0
System.out.print(0);
}
75.字符连续出现最大次数
输入一串字符串
字符串长度不超过100
查找字符串中相同字符连续出现的最大次数
输入描述
输入只有一行,包含一个长度不超过100的字符串
输出描述
输出只有一行,输出相同字符串连续出现的最大次数
说明:
输出
示例1:
输入
hello
输出
2
示例2:
输入
word
输出
1
示例3:
输入
aaabbc
输出
3
字符串区分大小写
// 字符连续出现最大次数
public static void test075() {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
String[] split = line.split("");
// 出现次数,初始值为1
int sum = 1;
// 最大次数
int res = 0;
for (int i = 0; i < split.length; i++) {
// 连续相同字符串
while (i + 1 < split.length && split[i].equals(split[i + 1])) {
sum++;
i++;
}
// 比较出最大的
res = Math.max(res, sum);
// 初始化出现次数
sum = 1;
}
System.out.println(res);
}
74.最少停车数
特定大小的停车场 数组cars表示
其中1表示有车 0表示没车
车辆大小不一,小车占一个车位(长度1)
货车占两个车位(长度2)
卡车占三个车位(长度3)
统计停车场最少可以停多少辆车
返回具体的数目
输入描述:
整型字符串数组cars
其中1表示有车0表示没车
数组长度<1000
输出描述:
整型数字字符串
表示最少停车数
示例1:
输入
1,0,1
输出
2
说明:
一个小车占第一个车位
第二个车位空,一个小车占第三个车位
最少有两辆车
示例2:
输入:
1,1,0,0,1,1,1,0,1
输出:
3
说明:
一个货车占第1,2个车位
第3,4个车位空
一个卡车占第5,6,7个车位
第8个车位空
一个小车占第9个车位
最少3俩个车
// 最少停车数
public static void test074() {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
String[] split = line.split(",");
// 连续1的次数
int count = 0;
// 找出所有的连续1的次数,存在list中
List<Integer> list = new ArrayList<>();
for (int i = 0; i < split.length; i++) {
// 找出连续1的次数
while (i < split.length && "1".equals(split[i])) {
count++;
i++;
}
// 连续1的次数大于0,存入list中
if (count != 0) {
list.add(count);
}
// 初始化
count = 0;
}
int res = 0;
for (int i = 0; i < list.size(); i++) {
// 累加结果,算出能停几辆卡车
res += list.get(i) / 3;
// 如果%3有剩余的,则再加一辆,不用管余1还是余2,最小都是一辆
if (list.get(i) % 3 != 0) {
res++;
}
}
System.out.println(res);
}
73.字母多条件排序
给出一个只包含字母的字符串,
不包含空格,统计字符串中各个子字母(区分大小写)出现的次数,
并按照字母出现次数从大到小的顺序输出各个字母及其出现次数
如果次数相同,按照自然顺序排序,且小写字母在大写字母之前
输入描述:
输入一行仅包含字母的字符串
输出描述:
按照字母出现次数从大到小的顺序输出各个字母和字母次数,
用英文分号分割,
注意末尾的分号
字母和次数中间用英文冒号分隔
示例:
输入: xyxyXX
输出:x:2;y:2;X:2;
说明:每个字符出现的次数为2 故x排在y之前
而小写字母x在大写X之前
示例2:
输入:
abababb
输出:
b:4;a:3
说明:b的出现个数比a多 故排在a前
// PS:这道题按我的理解我做的是对的,先按次数排序,排完在按a~z A~Z排序。但是案例给的不清楚,或许可以 a~z中按次数排序,后在A~Z中按次数排序,就是小写在前,大写在后
// 字母多条件排序
public static void test073() {
Scanner sc = new Scanner(System.in);
char[] chars = sc.nextLine().toCharArray();
// 用一个map,key存字符,value存字符出现次数
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (map.containsKey(c)) {
map.put(c, map.get(c) + 1);
} else {
map.put(c, 1);
}
}
// 小写字符的ACSII码大于大写字符, a~z 递增 A~Z递增
Set<Map.Entry<Character, Integer>> entries = map.entrySet();
// 排序 排序规则:当返回的数字大于0,则进行换位置,否则不换
entries.stream().sorted((s1, s2) -> {
// 按次数排序
if (s1.getValue() - s2.getValue() != 0) {
return s2.getValue() - s1.getValue();
}
Character key1 = s1.getKey();
Character key2 = s2.getKey();
// a~z 两个小写字母之间的比较
if (key1.compareTo('A') > 25 && key2.compareTo('A') > 25) {
return key1 - key2; // 字符a~z A~Z之间加减返回数字
}
// A~Z 两个大写字母之间的比较
if (key1.compareTo('A') < 26 && key2.compareTo('A') < 26) {
return key1 - key2;
}
// a~z 混 A~Z 大小写字母之间的比较,大写在后
return -(key1 - key2);
}).forEach((s) -> {
System.out.print(s.getKey() + ":" + s.getValue() + ";");
});
}
71. 交叉排序
现在有一队小朋友,他们高矮不同,
我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。
我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,
每一个“高”位置的小朋友要比相邻的位置高或者相等;
每一个“矮”位置的小朋友要比相邻的位置矮或者相等;
要求小朋友们移动的距离和最小,第一个从“高”位开始排,输出最小移动距离即可。
例如,在示范小队{5,3,1,2,3}中,{5, 1, 3, 2, 3}是排序结果。
{5, 2, 3, 1, 3} 虽然也满足“高”“矮”“高”“矮”顺序排列,
但小朋友们的移动距离大,所以不是最优结果。
移动距离的定义如下所示:
第二位小朋友移到第三位小朋友后面,移动距离为1,
若移动到第四位小朋友后面,移动距离为2;
输入描述:
排序前的小朋友,以英文空格的正整数:
4 3 5 7 8
注:小朋友<100个
输出描述:
排序后的小朋友,以英文空格分割的正整数:
4 3 7 5 8
备注:4(高)3(矮)7(高)5(矮)8(高),
输出结果为最小移动距离,只有5和7交换了位置,移动距离都是1.
示例一:
输入
4 1 3 5 2
输出
4 1 5 2 3
示例二:
输入
1 1 1 1 1
输出
1 1 1 1 1
说明:相邻位置可以相等
示例三:
输入:
xxx
输出
[]
说明:出现非法参数情况,返回空数组
// PS:对案例
// 输入
// 4 1 3 5 2
// 输出
// 4 1 5 2 3
// 有疑问,最有不应该是 4 1 3 2 5 吗??? 代码是照着案例写的,我认为通过率没有100%,没有测试数据,网上好多答案也是这样子写的,懵了
// 交叉排序
public static void test071() {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
List<Integer> list = new ArrayList<>();
try {
String[] split = line.split(" ");
for (int i = 0; i < split.length; i++) {
list.add(Integer.parseInt(split[i]));
}
}catch (Exception e){
// 输入异常情况
System.out.println("[]");
return;
}
// 用于判断当前是高矮 还是 矮高
boolean flag = true;
for (int i = 0; i + 1 < list.size(); i++) {
if (flag) {
// 高 矮
if (list.get(i) < list.get(i + 1)) {
// 是矮 高,则交换位置
int temp = list.get(i);
list.set(i, list.get(i + 1));
list.set(i + 1, temp);
}
// 判断完高 矮,切换为 矮 高
flag = false;
} else {
// 矮 高
if (list.get(i) > list.get(i + 1)) {
// 是高 矮,则交换位置
int temp = list.get(i);
list.set(i, list.get(i + 1));
list.set(i + 1, temp);
}
// 判断完矮 高,切换为高 矮
flag = true;
}
}
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
}
70.水仙花数
所谓的水仙花数是指一个n位的正整数其各位数字的n次方的和等于该数本身,
例如153=1^3+5^3+3^3,153是一个三位数
输入描述
第一行输入一个整数N,
表示N位的正整数N在3-7之间包含3,7
第二行输入一个正整数M,
表示需要返回第M个水仙花数
输出描述
返回长度是N的第M个水仙花数,
个数从0开始编号,
若M大于水仙花数的个数返回最后一个水仙花数和M的乘积,
若输入不合法返回-1
示例一:
输入
3
0
输出
153
说明:153是第一个水仙花数
示例二:
输入
9
1
输出
-1
// 水仙花数
public static void test070() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
if (n < 3 || n > 7) {
System.out.println(-1);
return;
}
// 起始数
int start = (int) Math.pow(10, n - 1);
// 终止数
int end = (int) Math.pow(10, n);
List<Integer> reslist = new ArrayList<>();
for (int i = start; i < end; i++) {
int sum = 0;
// 求每位数的简单解法
// String[] split = (i + "").split("");
// for (String s : split) {
// sum += Math.pow(Integer.parseInt(s), n);
// }
// 算出每位数
List<Integer> list1 = singleNum(i);
for (Integer s : list1) {
// 每位数进行n次方并累加
sum += Math.pow(s, n);
}
// 满足要求的放进结果集中
if (sum == i) {
reslist.add(i);
}
}
if (m >= reslist.size()) {
System.out.println(reslist.get(reslist.size() - 1) * m);
} else {
System.out.println(reslist.get(m));
}
}
/**
* 将一个整型数从后往前输出单个数字
* @param num
* @return
*/
public static List<Integer> singleNum(int num){
List<Integer> list = new ArrayList<>();
while (num > 0) {
int singleNum = num % 10;
list.add(singleNum);
num = num /10;
}
return list;
}
69.消除相邻且相同字母
游戏规则:
输入一个只包含英文字母的字符串,
字符串中的两个字母如果相邻且相同,就可以消除。
在字符串上反复执行消除的动作,
直到无法继续消除为止,此时游戏结束。
输出最终得到的字符串长度.
输入描述:
输入原始字符串str
只能包含大小写英文字母,字母的大小写敏感,
str长度不超过100
输出描述
输出游戏结束后,最终得到的字符串长度
示例一:
输入
gg
输出
0
说明 gg可以直接消除 得到空串 长度为0
示例2
输入:
mMbccbc
输出
3
说明mMbccbc中 可以先消除cc 此时变为mMbbc
再消除 bb 此时变成mMc
此时没有相同且相邻的字符 无法继续消除
最终得到字符串mMc 长度为3
备注:
输入中包含非大小写英文字母时
均为异常输入
直接返回0
// PS:字符串中的<两个>字母如果相邻且相同,就可以消除,相同的字符只能两两删除,比如有3个只能删2个
// 消除相邻且相同字母
public static void test069() {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
// replaceAll 可以用正则表达式; [a-zA-Z]:匹配a-zA-Z其中一个
//String newLine = line.replaceAll("[a-z]|[A-Z]", "");
String newLine = line.replaceAll("[a-zA-Z]", "");
// 异常输入
if (newLine.length() > 0) {
System.out.println(0);
return;
}
for (int i = 0; i < line.length() - 1; i++){
if (line.charAt(i) == line.charAt(i+1)) {
// 两个字符相等,则消除
line = line.replaceFirst(line.substring(i, i+2), "");
// 需要把指针回到前一个字符
if (i == 0){
i = i - 1; // 因为是开头,只需要-1抵消后面的i++
} else {
i = i - 2; // -1回退到前一个字符,再-1抵消后面的i++
}
}
}
// System.out.println(line);
System.out.println(line.length());
}