喊七游戏
-
N个人围成一圈,按顺时针从1 - N编号
-
编号为1的人从1开始喊数,下一个人喊得数字是上一个人喊得数字+1,
当将要喊出数字7的倍数或者含有7的话,不能喊出,而是要喊过。 -
假定N个人都没有失误,当喊到数字k时,可以统计每个人喊“过"的次数。
-
现给定一个长度N的数组,存储打乱的每个人喊”过"的次数,请把它还原成正确顺序。
即数组的第i个元素存储编号i的人喊“过“的次数
输入:
每个人喊过的次数(乱序),空格分隔
输出:
按1-N 顺序正确的喊 ‘过’ 的次数,空格分隔
示例一
输入:
0 1 0
输出:
1 0 0
输入:
0 0 0 2 1
输出
0 2 0 1 0 输出每个值,并空格隔开
说明
一共3次喊过
发生在7 14 17
编号为2的遇到7 17
编号为4的遇到14
思路:
- 根据输入序列
- 得到总人数 n;
- 求和得到所有的“过”的次数 total_count;
- 字典存储每人喊‘过’的次数;key -> 0-n
- 喊数从start=1开始,不断循环
- 判断start是否满足含有7或者是7的倍数,满足则给对应的人(start%n)喊‘过’次数+1,且cur_count +=1(初始为0)
- 如果cur_count < total_count ,即还没达到喊‘过’的总次数,start += 1 && continue
- 否则break
- 最后将数据按照1-n的顺序放入列表,并依次输出 ;
- 注意无法直观地排序。
python实现:
# 思路中的方法:
class SaySeven:
def solution(self, pass_list):
# 总人数
n = len(pass_list)
# 总计喊 ‘过’的次数
total_count = sum(pass_list)
cur_count = 0
# 每人喊‘过’的次数
times_by_person = { i: 0 for i in range(n)}
# 从1开始喊
start = 1
while True:
if '7' in str(start) or start % 7 == 0:
key = start % n
times_by_person[key] += 1
cur_count += 1
# 喊‘过’的次数 尚未达到总数
if cur_count < total_count:
start += 1
continue
else:
break
# 从1-n 顺序输出喊‘过’的次数
result = [0] * n
for key in times_by_person.keys():
if key != 0:
result[key-1] = times_by_person.get(key)
else:
val = times_by_person.get(key)
key = key + n - 1
result[key] = val
print(" ".join(list(map(str, result))))
if __name__ == '__main__':
say_seven = SaySeven()
while True:
try:
pass_list = list(map(int, input("输入喊过次数:").strip().split()))
say_seven.solution(pass_list)
except KeyboardInterrupt:
break
# 方法二,先计算出最高喊到几,才满足喊‘过’的总次数;
def predict_k(total_times):
""" predict value of k """
pre_times = 0
k = 1 # 从1开始
while pre_times != total_times:
pre_times = 0
k += 1
for i in range(1, k+1):
if i % 7 == 0 or '7' in str(i):
pre_times += 1
return k
# 依次喊数,遇过则对应列表索引+1
def skip_times_by_person(n, k, origin):
for i in range(1, k + 1):
if i % 7 == 0 or "7" in str(i):
# 过
if i % n != 0:
idx = i % n
idx -= 1
origin[idx] += 1
else:
origin[-1] += 1
return origin
if __name__ == '__main__':
skip_times_list = list(map(int, input().strip().split()))
# 人数
n = len(skip_times_list)
# 总的‘过’次数
total_times = sum(skip_times_list)
# 预测k值
k = predict_k(total_times)
print("current k:", k)
# 原始每个人喊‘过’的次数均为0
origin = [0 for i in range(n)]
# 1-k 每个人喊‘过’的次数
skip_times_by_person(n, k, origin)
for i in origin:
print(i, end=" ")
java实现:
import java.util.Scanner;
public class Main0016 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String line = scanner.nextLine();
solution(line);
}
}
private static void solution(String line) {
String[] split = line.split(" ");
int sum = 0;
for (String s : split) {
sum += Integer.parseInt(s);
}
int[] res = new int[split.length];
int j = 0;
for (int i = 1; i < 300; i++, j++) {
if (j == split.length) j = 0;
if (i % 7 == 0 || (i + "").contains("7")) {
res[j] += 1;
}
int sum1 = 0;
for (int re : res) sum1 += re;
if (sum == sum1) break;
}
for (int i = 0; i < res.length; i++) {
System.out.print(res[i]);
if (i != res.length - 1) {
System.out.print(" ");
}
}
}
}
找出同班的小朋友
- 两个班的小朋友排队时混在了一起,每个小朋友知道自己与前面一个小朋友是不是同班;
- 帮忙把同班的小朋友找出来,小朋友的编号为整数;
- 与前面一个小朋友同班用Y表示,不同班用N表示
输入:
小朋友编号 / 是否同班
比如 6/N 2/Y 3/N 4/Y 共4位小朋友
6和2是同班,2和3不同班,3和4同班
0 < 小朋友编号 < 999 标志位只能为Y or N;
输出:
每一行是同一个班小朋友的编号升序排列 且用空格分开;
首个小朋友编号小的班级在第一行输出;
如果输入不符合要求输出字符串ERROR
示例一
输入:
1/N 2/Y 3/N 4/Y
输出:
1 2
3 4
说明
2的同班标记为Y因此和1同班
3的同班标记位N因此和1,2不同班
4的同班标记位Y因此和3同班
实例二:
输入:
a/N 2/Y 3/N 4/Y
输出:
ERROR
实例三:
输入:
5/Y 7/N 3/N 2/Y 10/Y 6/N
输出:
2 3 5 10
6 7
思路:
- 判断输入是否有效,无效输出ERROR;
- 学生编号在(0-999)
- 是否同班标志为Y or N;
- 必须一个 / 分割;
- 班级以字典表示,0班,1班;
- 0:[ ] , 1: [ ]
- label 表示前一个学生的班级,默认为0;
- label = (label + 1) % 2 表示班级的切换;
- 第一个学生直接加入0班级,从第二个学生开始遍历,判断是否与前一个学生同班,相同则直接追加到label表示的班级;否则label切换,并存入切换后的班级;
- 最终对两个班级的学生编号排序,并输出;
python实现:
# __author__ = "laufing"
#
# 1N 2/Y 3/N 4/Y
# ERROR
# 5/Y 7/N 3/N 2/Y 10/Y 6/N
# 2 3 5 10
# 6 7
class FindSameClass:
def solution(self, stu_list):
# 判断是否有效
if self.invalid(stu_list):
print("ERROR")
return
# 有效则开始查找 1/N 2/Y 3/N 4/Y
cur_classes = {0: [], 1: []}
label = 0 # 表示前一个学生的班级
cur_classes.get(label).append(int(stu_list[0].split("/")[0]))
for stu in stu_list[1:]:
# stu like '1/N'
stu_id, flag = stu.split("/")
if flag == "Y":
cur_classes.get(label).append(int(stu_id))
else:
label = (label + 1) % 2
cur_classes.get(label).append(int(stu_id))
class_0 = sorted(cur_classes.get(0))
class_1 = sorted(cur_classes.get(1))
if class_0[0] <= class_1[0]:
[print(i, end=" ") for i in class_0]
print("")
[print(i, end=" ") for i in class_1]
else:
[print(i, end=" ") for i in class_1]
print("")
[print(i, end=" ") for i in class_0]
def invalid(self, stu_list):
if stu_list:
result = list(filter(self.func, stu_list))
return len(result) < len(stu_list)
return True
def func(self, stu):
# 过滤出有效的学生编号
try:
stu_id, flag = stu.split("/")
return 0 < int(stu_id) < 999 and flag in ("Y", "N")
except:
return False
if __name__ == '__main__':
find_same_class = FindSameClass()
while True:
try:
stu_list = input("输入:").strip().split()
find_same_class.solution(stu_list)
except KeyboardInterrupt:
break
java实现:
import java.util.Scanner;
import java.util.TreeSet;
public class Main0038 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String line = scanner.nextLine();
solution(line);
}
}
private static void solution(String line) {
String[] stus = line.split(" ");
try {
TreeSet<Integer> c1 = new TreeSet<>();
TreeSet<Integer> c2 = new TreeSet<>();
boolean is1 = true;
for (int i = 0; i < stus.length; i++) {
String[] split = stus[i].split("/");
String id = split[0];
String same = split[1];
if (i == 0) {
c1.add(Integer.parseInt(id));
continue;
}
if ("N".equals(same)) is1 = !is1;
(is1 ? c1 : c2).add(Integer.parseInt(id));
}
StringBuilder b1 = new StringBuilder();
for (Integer id : c1) b1.append(id).append(" ");
if (c2.size() > 0) {
StringBuilder b2 = new StringBuilder();
for (Integer id : c2) b2.append(id).append(" ");
if (c1.first() < c2.first()) {
System.out.println(b1.toString().trim());
System.out.println(b2.toString().trim());
} else {
System.out.println(b2.toString().trim());
System.out.println(b1.toString().trim());
}
} else {
System.out.println(b1.toString().trim());
}
} catch (Exception e) {
System.out.println("ERROR");
}
}
}
斗地主
游戏中,扑克牌由小到大的顺序为3 4 5 6 7 8 9 10 J Q K A 2
玩家可以出的扑克牌阵型有,单张,对子,顺子,飞机,炸弹等
其中顺子的出牌规则为,由至少5张由小到大连续递增的扑克牌组成
且不能包含2
例如:{3,4,5,6,7}、{3,4,5,6,7,8,9,10,J,Q,K,A}都是有效的顺子
而{J,Q,K,A,2}、{2,3,4,5,6}、{3,4,5,6}、{3,4,5,6,8}等都不是顺子
给定一个包含13张牌的数组,如果有满足出牌规则的顺子,请输出顺子
如果存在多个顺子,请每行输出一个顺子
且需要按照顺子的第一张牌的大小(必须从小到大)依次输出
如果没有满足出牌规则的顺子,请输出No
输入:
13张扑克牌,空格隔开,
每张扑克牌的数字都是合法的,并且不包括大小王:2 9 J 2 3 4 K A 7 9 A 5 6
不需要考虑输入为异常字符的情况
输出:
组成的顺子 3 4 5 6 7
示例一
输入:
2 9 J 2 3 4 K A 7 9 A 5 6
输出:
3 4 5 6 7
示例二
输入:
2 9 J 10 3 4 K A 7 Q A 5 6
输出:
3 4 5 6 7
9 10 J Q K A
示例三
输入:
2 9 9 9 3 4 K A 10 Q A 5 6
输出:
No
示例四
输入:
5 5 6 6 7 7 8 8 9 9 J K A
输出:
5 6 7 8 9
5 6 7 8 9
思路:
-
牌面字符列表删除所有的’2’(因为 ‘2’ 对顺子无用);
-
剩余的牌,从小到大排序得到 sorted_cards列表;
-
while len(set(sorted_cards)) >=5:
- while sorted_cards:
- 弹出一个数据data=sorted_cards.pop(0);
- 如果cur_seq列表为空,则直接追加;否则判断data与cur_seq[-1]的差值,差值为1则追加,差值为0则为重复的牌,将重复的牌追加到repeated_cards列表;
- 差值大于1,说明顺子肯定断裂,则将data重新插入到sorted_cards的首位;并判断cur_seq中所有牌是否组成顺子(length >=5 ), 若已组成顺子,则将其保存到result列表中,temp重新创建空列表; 若没有组成顺子,则直接清空temp列表。
- 内层循环结束,判断cur_seq中是否为顺子,是则存入result列表;否则清空;
- repeated_cards 重新放入sorted_cards,并清空repeated_cards;
- while sorted_cards:
-
最后输出结果
- result 列表有值,则判断是一个还是两个顺子,两个顺子时,需按照首张牌从小到大按行输出;
- result 为空,则输出No
python实现:
# __author__ = "laufing"
import random
class DouDZ:
def __init__(self):
self.mapping = { # 字符比较大小
"J": 11,
"Q": 12,
"K": 13,
"A": 14
}
def solution(self, card_list):
# 从小到大排序
cadidates = sorted(card_list, key=lambda i: self.mapping.get(i) if i in self.mapping else int(i))
result = []
cur_seq = []
repeated_card = []
while len(set(cadidates)) >= 5: # 去重后 长度>=5
while cadidates:
data = cadidates.pop(0)
if not cur_seq:
cur_seq.append(data)
# 当前值与前一个比较
elif self.calc_diff(cur_seq[-1], data) == 1:
cur_seq.append(data)
elif self.calc_diff(cur_seq[-1], data) == 0:
repeated_card.append(data)
else:
cadidates.insert(0, data)
# 出现非连续,判断当前是否组成顺子
if len(cur_seq) >= 5:
result.append(cur_seq.copy())
cur_seq.clear()
# cadidates 空时判断
if len(cur_seq) >= 5:
result.append(cur_seq.copy())
cur_seq.clear()
cadidates.extend(repeated_card)
repeated_card.clear()
self.print_result(result)
# 输出结果,多个(2个)顺子 按照顺子的首个数字从小到大依次输出
def print_result(self, result):
if len(result) == 1:
print(" ".join(result[0]))
return
elif len(result) == 0:
print("NO")
return
else:
result = sorted(result, key=lambda i: self.mapping.get(i[0]) if i[0] in self.mapping else int(i[0]))
for i in result:
print(" ".join(i))
def calc_diff(self, pre, cur): # 计算差值
a = self.mapping.get(pre) if pre in self.mapping else int(pre) # 字符数字
b = self.mapping.get(cur) if cur in self.mapping else int(cur)
return b - a
def dispatch_card(): # 随机发牌
all_cards = [
"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"
]
cards = []
while len(cards) < 13:
card = random.choice(all_cards)
if cards.count(card) < 4:
cards.append(card)
return cards
if __name__ == '__main__':
dou_dz = DouDZ()
while True:
try:
card_list = input("输入:").strip().split()
# card_list = dispatch_card()
print("card_list:", card_list)
# 删除2 2不能构成顺子
while "2" in card_list:
card_list.remove("2") #
# 找出顺子
dou_dz.solution(card_list)
except KeyboardInterrupt:
break
java实现:
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Main0117 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String line = scanner.nextLine();
solution(line);
}
}
private static void solution(String line) {
String[] split = line.split(" ");
String[] index = new String[13];
convert(split, index);
List<String> resSet = new LinkedList<>();
for (int i = 1; i < index.length; i++) {
int count = 0;
StringBuilder builder = new StringBuilder();
while (i < index.length && index[i] != null) {
builder.append(index[i]).append(" ");
count++;
i++;
}
if (count >= 5) {
resSet.add(builder.substring(0, builder.length() - 1));
}
}
if (resSet.size() == 0) {
System.out.println("No");
} else {
for (String res : resSet) {
System.out.println(res);
}
}
}
private static void convert(String[] split, String[] ints) {
for (String str : split) {
if (str.length() == 1) {
char c = str.charAt(0);
if (Character.isDigit(c)) {
ints[Character.digit(c, 10) - 2] = str;
} else {
switch (c) {
case 'A':
ints[12] = str;
break;
case 'J':
ints[9] = str;
break;
case 'Q':
ints[10] = str;
break;
case 'K':
ints[11] = str;
break;
default:
break;
}
}
} else {
ints[8] = str;
}
}
}
}
补种胡杨
某沙漠新种植 N 棵胡杨(编号 1-N ),排成一排,一个月后,有 M 棵胡杨未能成活。
现可补种胡杨 K 棵,请问如何补种(只能在原来的位置补种),可以得到最多的连续胡杨树?
输入:
N 总种植数量,1≤N≤100000
M 未成活胡杨数量,1≤M≤N
未成活的编号,从小到大排序
K 最多可以补种的数量,0≤K≤M
输出:
最多的连续胡杨棵数
示例一
输入:
5
2
2 4
1
输出
3
说明
补种到2或4结果一样,最多的连续胡杨棵树都是3。
示例二
输入
10
3
2 4 7
1
输出
6
说明
补种第7棵树,最多连续胡杨树棵数位6(5,6,7,8,9,10)
思路:
- 未成活的胡杨树之间距离越远,补种获取的连续棵数才可能越大;且必须连续补种。
- 补种k=1时,分别获取补种最左边1棵、补种中间1棵、补种最右边1棵的情况下的最大连续数;
- 补种k=2时,分别获取补种最左边2棵、补种中间2棵、补种最右边2棵的情况下的最大连续数;
- 总结规律,得到补种索引为range(m-k+1)
- 当补种索引为0,即最左边补种k棵时,取max(cur_max, dead[i+k] - 1)
- 当补种索引为最后一次,即最右边补种k棵 ,取max(cur_max, n - dead[i-1])
- 当补种中间的k棵时,取max(cur_max, dead[i+k] - dead[i-1] - 1)
python实现:
def solution(n, m, indies, k):
""" 必须连续地补未活的树 """
max_len = 0
# 控制补树的索引
for i in range(m - k + 1): # k为1、2、3.......
if i == 0: # 补最左边上的k个
max_len = max(max_len, indies[i + k] - 1)
elif i == m - k: # 补最右边的k个
max_len = max(max_len, n - indies[i - 1])
else:
max_len = max(max_len, indies[i + k] - indies[i - 1] - 1)
return max_len
if __name__ == '__main__':
n, m = int(input().strip()), int(input().strip())
m_id_list = list(map(int, input().strip().split()))
k = int(input().strip())
print(solution(n, m, m_id_list, k))
java实现:
import java.util.Scanner;
public class Main0256 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int N = scanner.nextInt();
int M = scanner.nextInt();
int[] indies = new int[M];
for (int i = 0; i < M; i++) {
indies[i] = scanner.nextInt();
}
int K = scanner.nextInt();
System.out.println(solution(N, M, indies, K));
}
}
public static int solution(int n, int m, int[] indies, int k) {
int maxLen = 0;
for (int i = 0; i <= m - k; i++) {
if (i == 0) {
maxLen = Math.max(maxLen, indies[i + k] - 1);
} else if (i == m - k) {
maxLen = Math.max(maxLen, n - indies[i - 1]);
} else {
maxLen = Math.max(maxLen, indies[i + k] - indies[i - 1] - 1);
}
}
return maxLen;
}
}
ip地址转为整数
- 如 128#0#255#255 为一个虚拟IP,转换为32位整数的结果为2147549183;1#0#0#0,转换为32位整数的结果为16777216
- 现以字符串形式给出一个虚拟IPv4地址,每一节范围分别为(1~128)#(0~255)#(0~255)#(0~255),
每个IPv4地址只能对应到唯一的整数上。
如果是非法虚拟IP,输出invalid IP - 需对非法虚拟IP(空串,含有IP地址中不存在的字符,数值超限)进行识别,输出invalid IP
输入:
虚拟IPv4地址格式字符串
输出:
转换的整型
示例一
输入:
100#101#1#5
输出:
1684340997
示例一
输入:
1#2#3
输出:
invalid IP
思路:
- 验证虚拟IP的有效性;
- 字符串以#分割,并映射为int,每个整数使用bin转为二进制,并截取(0b不要)拼接出一个八位的二进制;
- 所有二进制依次拼接成一个32位的二进制字符串;
- 32位字符串截取出从1开始的部分,并转为整数(加权求和)。
python实现:
def is_valid(s):
if not s:
return False
if "#" not in s:
return False
try:
a, b, c, d = s.split("#")
except:
return False
# 不是数值情况
if not a.isdigit() or not b.isdigit() or not c.isdigit() or not d.isdigit():
return False
# 数值不在范围内
if not 128 >= int(a) >= 1 or not 255 >= int(b) >= 0 or not 255 >= int(c) >= 0 or not 255 >= int(d) >= 0:
return False
return True
def bin_str_to_int(bin_str):
idx = bin_str.find("1")
if idx == -1:
return 0
int_val = 0
s = bin_str[idx:]
s_len = len(s)
base = 2**(s_len - 1)
for i in s:
# 每个字符
if i == "1":
int_val += 1 * base
base /= 2
return int_val
if __name__ == '__main__':
# s = "128#0#255#255"
s = input()
if is_valid(s):
# 有效的IP
data_list = map(int, s.split("#"))
bin_str = ""
for v in data_list:
temp_bin = bin(v)[2:]
if len(temp_bin) < 8:
temp_bin = "0" * (8 - len(temp_bin)) + temp_bin
bin_str += temp_bin
int_val = bin_str_to_int(bin_str)
print(int(int_val))
else:
# 无效的IP
print("invalid IP")
java实现:
import java.util.Scanner;
public class Main0130 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String ip = scanner.nextLine();
solution(ip);
}
}
private static void solution(String ip) {
String[] strings = ip.split("#");
int len = strings.length;
long count = 0;
boolean isF = true;
if (len == 4) {
for (int i = 0; i < len; i++) {
long n = Integer.parseInt(strings[i]);
if (i == 0 && (n < 1 || n > 128)) {
isF = false;
break;
} else if (n < 0 || n > 255) {
isF = false;
break;
}
count += n << (8 * (3 - i));
}
} else {
isF = false;
}
if (isF) {
System.out.print(count);
} else {
System.out.print("invalid IP");
}
}
}
响应报文的时间
-
HOST收到查询报文,解析出最大响应时间后,需要在MaxResponseTime(s) 回应一个响应报文;
-
在响应上一个报文前,若收到一个新的查询报文,则取两者最大时间的最小值,返回响应;
-
每个查询报文的最大响应时间计算:
当MaxRespCode < 128, MaxRespTime = MaxRespCode;
当MaxRespCode >= 128, MaxRespTime = (mant | 0x10) << (exp + 3);
如下解释:
MaxRespCode转为二进制 为10000000
|1|000|0000|
|1|exp|mant|
mant为MaxRespCode的低四位,exp为高5-7位;
MaxRespCode 【0, 255】;
输入:
第一行为查询报文个数 C,
后续每行分别为HOST收到报文时间T,MaxRespCode M
输出:
HOST发送响应报文的时间
示例一
输入:
3
0 20
1 10
8 20
输出
11
说明:
第0s收到1个报文,其MaxRespCode为20秒(<128),MaxRespTime则为20s,故要到0+20=20s 返回响应;
第1s收到第2个报文,MaxRespCode为10,MaxRespTime则为10s,
故要到1+10=11s响应,与上个报文的响应时间比较,得最小值为11s;
第8s收到第3个报文,MaxRespCode为20,MaxRespTime则为20s,则要到8+20=28s响应,与上个响应取最小值为11s
故输出 11
示例二
输入:
2
0 255
200 60
输出:
260
说明
第0s 收到第1个报文,MaxRespCode 为255s,MaxRespTime则为(15|0x10)<<(7+3)=31744s ,(mant=15, exp=7) ; 则在0+31744s 返回响应。
第200s 收到第2个报文,MaxRespCode 为60s,MaxRespTime为60s,则要到200+60=260秒响应,与上个报文取最小值 为260s 。
思路:
- MaxRespCode是否小于128,计算出MaxRespTime,再加上收到报文的时间,就是响应的时间;
- 所有的响应时间取最小值;
python实现:
def get_int(s):
idx = s.find("1")
if idx == -1:
return 0
s_ = s[idx:]
n = len(s_)
base = 2 ** (n - 1)
int_val = 0
for i in s_:
if i == "1":
int_val += 1 * base
base /= 2
return int(int_val)
def calc_max_resp_time(max_resp_code):
# 响应code转为二进制
bin_str = bin(max_resp_code)
bin_str = bin_str[2:]
if len(bin_str) < 8:
bin_str = "0" * (8 - len(bin_str)) + bin_str
# 整数
mant = get_int(bin_str[-4:])
exp = get_int(bin_str[1:4])
return (mant | 0x10) << (exp + 3)
if __name__ == '__main__':
# 报文数
c = int(input().strip())
package = []
for i in range(c):
p = list(map(int, input().strip().split()))
package.append(p)
print(package)
resp_t = 2**32 - 1
for p in package:
if p[1] < 128:
max_resp_time = p[1]
else:
max_resp_time = calc_max_resp_time(p[1])
resp_t = min(resp_t, max_resp_time + p[0])
print(resp_t)
java实现:
import java.util.Scanner;
public class Main0229 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int C = scanner.nextInt();
int[] T = new int[C];
int[] M = new int[C];
for (int i = 0; i < C; i++) {
T[i] = scanner.nextInt();
M[i] = scanner.nextInt();
}
int responseTime = solution(C, T, M);
System.out.println(responseTime);
}
}
private static int solution(int C, int[] T, int[] M) {
int responseTime = 0;
for (int i = 0; i < C; i++) {
int maxRespTime = calculateMaxRespTime(M[i]);
int newRespTime = T[i] + maxRespTime;
if (i == 0 || newRespTime < responseTime) {
responseTime = newRespTime;
}
}
return responseTime;
}
private static int calculateMaxRespTime(int maxRespCode) {
if (maxRespCode < 128) {
return maxRespCode;
} else {
int exp = (maxRespCode & 0x70) >> 4;
int mant = maxRespCode & 0x0F;
return (mant | 0x10) << (exp + 3);
}
}
}
事件推送
- 同一个数轴X上有两类点的集合A={A1, A2, …, Am}和B={B1, B2, …, Bn},
Ai和Bj均为正整数,A、B已经按照从小到大排好序,A、B均不为空; - 给定一个距离R(正整数),
列出同时满足如下条件的所有(Ai, Bj)数对:- Ai <= Bj;
- Ai, Bj之间的距离小于等于R;
- 在满足1,2的情况下,每个Ai只取最近的Bj,形成数对;有重复的最近Bj只需第一个。
- 输出结果按Ai从小到大的顺序排序
输入:
第一行三个正整数m,n,R
第二行m个正整数,表示集合A
第三行n个正整数,表示集合B
1 <= R <= 100000,1 <= n,m <= 100000,1 <= Ai,Bj <= 1000000000
输出:
每个数对输出一行,Ai和Bj以空格隔开
示例一
输入
4 5 5
1 5 5 10
1 3 8 8 20
输出
1 1
5 8
5 8
思路:
- 遍历A集合,依次组成满足条件的数对;
- 每个 A i {A_i} Ai只与距离最近的 B j {B_j} Bj组成
- 所有数对追加到一个列表中;
- 遍历输出每个数对
python实现:
if __name__ == '__main__':
m, n, r = list(map(int, input().strip().split()))
a_list = list(map(int, input().strip().split()))
b_list = list(map(int, input().strip().split()))
result = []
for i in a_list:
temp = []
for j in b_list:
if i <= j and abs(i - j) <= r:
if not temp:
temp.append((i, j))
else:
pre_dist = temp[-1][1] - temp[-1][0]
cur_dist = j - i
if cur_dist < pre_dist:
temp.pop()
temp.append((i, j))
if temp:
result.extend(temp)
for p in result:
print(p[0], " ", p[1])
java实现:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main0132 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int m = scanner.nextInt();
int n = scanner.nextInt();
int R = scanner.nextInt();
int[] a = new int[m];
int[] b = new int[n];
for (int i = 0; i < m; i++) {
a[i] = scanner.nextInt();
}
for (int i = 0; i < n; i++) {
b[i] = scanner.nextInt();
}
solution(R, a, b);
}
}
private static void solution(int R, int[] a, int[] b) {
int index = 0;
List<int[]> list = new ArrayList<>();
for (int j : a) {
int[] ints = new int[2];
while (index < b.length) {
if (j <= b[index] && b[index] - j <= R) {
ints[0] = j;
ints[1] = b[index];
list.add(ints);
break;
}
index++;
}
}
list.forEach(e -> System.out.println(e[0] + " " + e[1]));
}
}
 ;
数列还原
- 有一个数列A[n],A[n+1]都是A[n]的描述数字
- 其中A[0]=1
规则如下
A[0] = 1
A[1] = 11 表示A[0]从左到右连续出现了1次1
A[2] = 21 表示A[1]从左到右连续出现了2次1
A[3] = 1211 表示A[2]从左到右连续出现了一次2,又连续出现了一次1
A[4] = 111221 表示A[3]从左到右连续出现了一次1又连续出现了一次2又连续出现了2次1
输入:
数字n
输出:
数列第n项 A[n]
示例一
输入:
4
输出:
111221
思路:
- 依次遍历求A[1]、A[2]、…直到A[n];
- 在描述前一项时,遍历它的字符串并统计每个数出现了几次;
- 当出现不一样的数字时,拼接之前统计的count + char到字符串中。
python实现:
def calc_n_item(n):
pre = "1"
if n == 0:
print(pre)
return
for i in range(1, n + 1): # 4
# 拼接结果
result = ""
# pre 代表前一项
first_char = pre[0] # 前一项的首个字符
count = 1 # 计数
for j in range(1, len(pre)):
if pre[j] == first_char:
count += 1
else:
result += str(count) + first_char
count = 1
first_char = pre[j]
result += str(count) + first_char
pre = result
print(result)
if __name__ == '__main__':
n = int(input().strip())
calc_n_item(n)
java实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int n = scanner.nextInt();
solution(n);
}
}
private static void solution(int n) {
String content = "1";
if (n == 0) {
System.out.println(content);
return;
}
for (int i = 1; i <= n; i++) {
// 字符串构建对象
StringBuilder next = new StringBuilder();
char[] chars = content.toCharArray();
char last = chars[0];
int count = 1;
for (int j = 1; j < chars.length; j++) {
if (chars[j] == last) count++;
else {
next.append(count).append(last);
count = 1;
last = chars[j];
}
}
next.append(count).append(last);
content = next.toString();
}
System.out.println(content);
}
}
数组组成的最小数字
- 给定一个整型数组,请从该数组中选择3个元素组成最小数字并输出;
- 如果数组长度小于3,则选择数组中所有元素来组成最小数字;
输入
数组元素
0 < 数组长度 <= 100,
0 < 整数的取值范围 <= 10000。
输出:
由3个元素组成的最小数字,
如果数组长度小于3,则所有元素组成的最小数字。
示例一
输入:
21,30,62,5,31
输出:
21305
示例二
输入
5,21
输出
215
思路:
- 数组一个元素,则最小数输出元素本身;
- 数组有两个元素时,则使用这两个元素组成最小数【简单比较即可】;
- 数组有三个及以上元素时
- 数组升序排序,并分片出前三个最小的元素;
- 三个最小元素的数组冒泡升序排序,期间两个元素比较大小规则为谁在前面组成的数值小,即该元素小。
- 最后将 升序排序后 的三元素 拼接为字符串。
python实现:
def great_than(v1, v2):
value1 = str(v1) + str(v2)
value2 = str(v2) + str(v1)
return int(value1) > int(value2)
def clac_min_val(alist):
n = len(alist)
if n == 1:
print(alist[0])
return
elif n == 2:
# 选择两个元素 组成最小数字
a, b = alist
v1 = str(a) + str(b)
v2 = str(b) + str(a)
val = v1 if int(v1) < int(v2) else v2
print(val)
return
# 三个及以上的数字
alist.sort()
min_list = alist[:3]
min_list_len = len(min_list)
for i in range(min_list_len-1):
for j in range(min_list_len-1-i):
if great_than(min_list[j], min_list[j+1]):
min_list[j], min_list[j+1] = min_list[j+1], min_list[j]
result = ""
for v in min_list:
result += str(v)
print(result)
if __name__ == '__main__':
# alist = "21,30,62,5,31".split(",")
alist = input().strip().split(",")
alist = list(map(int, alist))
clac_min_val(alist)
java实现:
import java.util.*;
public class Main {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String line = scanner.nextLine();
solution(line);
}
}
private static void solution(String line) {
String[] split = line.split(",");
int len = split.length;
StringBuilder builder = new StringBuilder();
if (len == 1) {
builder = new StringBuilder(split[0]);
} else {
List<String> list = new ArrayList<>();
int[] ints = new int[len];
for (int i = 0; i < len; i++) {
ints[i] = Integer.parseInt(split[i]);
}
Arrays.sort(ints);
int numsLen;
if (len == 2) {
numsLen = 2;
} else {
numsLen = 3;
}
for (int i = 0; i < numsLen; i++) {
list.add(String.valueOf(ints[i]));
}
Collections.sort(list);
for (int i = 0; i < numsLen; i++) {
builder.append(list.get(i));
}
}
System.out.println(Integer.valueOf(builder.toString()));
}
}
字符串加密
- 给你一串未加密的字符串str,通过对字符串的每一个字母进行改变来实现加密,每一个字母str[i] 偏移 数组a[i]的值,
- 数组a 满足:a[0]=1, a[1]=2, a[2]=4
当i>=3时,数组元素a[i]=a[i-1]+a[i-2]+a[i-3],
例如:原文 abcde 加密后 bdgkr,其中偏移量分别是1,2,4,7,13。
输入:
第一行输入整数n(1 <= n <= 1000),表示有n组测试数据
后续每行为一组字符串,只含小写字母, 0 < 长度 <= 50
输出:
每组测试数据输出一行,表示字符串的密文
示例一
输入:
1
xy
输出:
ya
思路:
- 字符串中的每个字符转为ASCII码,再加 a[i] 对应的偏移量offset;
- 判断加offset后,对应的ASCII码值是否<=122
- 是,则转为字符,并拼接到一个新字符串中;
- 否,则需要%122 + 96 ,然后转为字符,并拼接到新字符串;
python实现:
def get_a_n(n):
if n == 0:
return 1
elif n == 1:
return 2
elif n == 2:
return 4
else:
return get_a_n(n-1) + get_a_n(n-2) + get_a_n(n-3)
def encrypt_str(str_list):
encrypt_result = []
for str_ in str_list:
result = ""
n = len(str_)
for i in range(n):
offset = ord(str_[i]) + get_a_n(i)
# 处理超出问题 z-122
if offset <= 122:
result += chr(offset)
else:
offset = (offset % 122) + 96
result += chr(offset)
encrypt_result.append(result)
return encrypt_result
if __name__ == '__main__':
n = int(input().strip())
origin_strings = []
for i in range(n):
origin_strings.append(input().strip())
en_result = encrypt_str(origin_strings)
for i in en_result:
print(i)
java实现:
import java.util.Scanner;
public class Main0094 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int n = Integer.parseInt(scanner.nextLine());
String[] strings = new String[n];
for (int i = 0; i < n; i++) {
strings[i] = scanner.nextLine();
}
solution(strings);
}
}
private static void solution(String[] strings) {
int[] a = {1, 2, 4};
long[] offsets = new long[50];
for (int i = 0; i < offsets.length; i++) {
if (i < 3) {
offsets[i] = a[i];
} else {
offsets[i] = offsets[i - 1] + offsets[i - 2] + offsets[i - 3];
}
}
for (String str : strings) {
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
chars[i] = (char) ((c - 97 + offsets[i]) % 26 + 97);
}
System.out.println(new String(chars));
}
}
}