一、 枚举
1. 纸牌游戏
【问题描述】
迪迪在乡下有一家小旅馆,他在那里过着平静的生活。
他喜欢长时间散步,看日落,和住在他酒店的游客打牌。
他最喜欢的游戏是“茅茅”,要玩茅茅,你需要一副一共52张牌。每张牌都有一个花色(方块D,梅花C,黑桃S,或红桃H)和一个等级(2,3,4,5,6,7,8,9,T, J, Q, K,或A)。
当且仅当牌的等级或花色与桌上的牌相同时,你才可以打牌。
为了检验你是否是个好搭档,迪迪为你准备了一项任务。现在给定桌上的牌和手中的五张牌,检查你是否至少能打一张牌。
【输入格式】
输入第一行一个单词代表桌上的牌,第一个字符代表等级,第二个字符代表花色。
输入第二行五个单词代表桌上的牌,规则同上。
输入中的所有卡片都不同。
【输出格式】
判断是否可以打牌,输出“YES” 或 “NO”。
大小写均可。
【例子】
第一个例子,桌上AS, 你可以打AD。
第二个例子,你无法打牌。
第三个例子,桌上4D,你可以打AD。
a = input()
b = input()
if a[0] in b or a[1] in b:
print("YES")
else:
print("NO")
2. 圣诞树
【问题描述】
圣诞节越来越近了!张老师打算装饰一棵圣诞树。
回想起上一次过圣诞节,仿佛还在上个月。
张老师手头有y个黄色的装饰物,b个蓝色的装饰物和r个红色的装饰物。对于张老师来说:一棵圣诞树是优美的,当且仅当用的蓝色装饰物的个数比黄色装饰物的个数多1且红色装饰物的个数比蓝色装饰物的个数多1。
那么请问张老师的圣诞树上最多有多少个装饰物呢?
【输入格式】
输入一行三个空格分开的整数y,b,r,含义如上。(1≤y≤100, 2≤b≤100, 3≤r≤100)
【输出格式】
输出一个整数表示答案。
【例子】
y, b, r = (int(x) for x in input().strip().split(' '))
flag = True
sum = 0
while flag:
if b >= y+1 and r >= y+2:
sum = 3*y + 3
print(sum)
flag = False
else:
y = y-1
3. 整数计算
【问题描述】
给出一个数 x, 求出两个整数 a and b 满足以下条件:
- 1 <= a,b <= x
- b 能整除 a (a 是 b 的倍数).
- a * b > x
- a / b < x
【输入格式】
输入一个整数 x (1 <= x <= 100).
【输出格式】
输出两个整数 a 和 b, 满足上述条件,如果不存在这样的两个数,则输出 -1.
【例子】
x = int(input())
flag = False
for a in range(1, x+1):
for b in range(1, x+1):
if a%b == 0 and a*b > x and a/b < x:
flag = True
break
if flag:
break
if not flag:
print('-1')
if flag:
print(a,b)
5. 圣诞树
【问题描述】
众所周知,魔法师龙老板想找一个女朋友。
但是那个女生喜欢三角形。
现在她有三根长度分别为a,b,c的魔法棒,他每分钟可以使用魔法使其中一个魔法棒的长度增加1,只有在最短的时间里龙老板组成一个三角形,那个女生才会答应他,请你帮助龙老板算出他最短用多长时间可以组成一个三角形
【输入格式】
输入仅一行,分别是三个整数a,b,c。分别代表三支魔棒的长度(1≤a,b,c≤100)。
【输出格式】
输出一个整数 — 龙老板使三根魔法棒拼成三角形所需的最少时间。
【例子】
提示:最长边小于另两边之和即可为三角形
a, b, c = (int(x) for x in input().strip().split(' '))
if a < b:
max = b
b = a
a = max
if a < c:
max = c
c = a
a = max
if a < b+c:
time = 0
else:
time = a - (b + c) + 1
print(time)
6. 海盗船
【问题描述】
小丑决定今天休息一下,于是他走进了一家游乐场。游乐场里有高矮胖瘦的小盆友。小丑的脑海中不禁浮现出一个画面:在一艘海盗船上坐着n个熊孩子,海盗船周期性地摇摆,每个周期都会在船头或者船尾甩出去一个熊孩子,但是体重大于k的熊孩子会牢牢地抱住船体不能被甩出去,他前面体重轻的由于体重大的也不会甩出去。小丑想知道最多能甩出去多少熊孩子。
【输入格式】
第一行输入两个整数n和k。1<=n,k<=100。
第二行输入n个孩子的体重(小于100)。按照从船头到船尾排列。
【输出格式】
输出一个整数——最多能甩出去的孩子数。
【例子】
n, k =(int(x) for x in input().strip().split(' '))
weight = [int(x) for x in input().strip().split(' ')]
sum = 0
for i in range(0, n):
if weight[i] <= k:
sum = sum + 1
else:
break
if sum == n:
print(sum)
else:
for i in range(n-1, 0, -1):
if weight[i] <= k:
sum = sum + 1
else:
break
print(sum)
7. 替换元素
【问题描述】
你有一个数组a1,a2,…,an。所有ai都是正整数。
在这个数组中,您可以选择三个不同的元素,如ai、aj和ak(i≠j;i≠k;j≠k),并将aj和ak之和赋给ai,即使ai=aj+ak。
在进行上述步骤多次操作后,你能让所有的ai低于或等于d?
【输入格式】
第一行包含一个整数t(1≤t≤2000)-测试用例数。
每个测试用例的第一行包含两个整数n和d(3≤n≤100;1≤d≤100)-数组a中的元素数和值d。
第二行包含n个整数a1,a2,…,an(1≤ai≤100)-数组a。
【输出格式】
对于每个测试用例,如果可以使用上述操作使所有元素ai小于或等于d,则打印YES。否则,打印NO。
你可以在任何情况下打印(例如,YES,YES,YES,YES都将被视为肯定答案)。
【例子】
在第一个测试用例中,我们可以证明我们不能使所有ai≤3。
在第二个测试用例中,所有ai已经小于或等于d=4。
例如,在第三个测试用例中,我们可以选择i=5,j=1,k=2,并使a5=a1+a2=2+1=3。数组a将变为[2,1,5,3,3]。
然后我们可以把a3=a5+a2=3+1=4。数组将变为[2,1,4,3,3],所有元素都小于或等于d=4。
t = int(input())
res = []
for i in range(0, t):
n, d = (int(x) for x in input().strip().split(' '))
a1 = [int(x) for x in input().strip().split(' ')]
a = sorted(a1) #排序,从小到大
if a[n-1] <= d:
res.append("YES")
else:
if a[1] + a[0] <= d:
res.append("YES")
else:
res.append("NO")
a.clear() #不写此句也可
for i in range(0, t):
print(res[i])
8 . 从左边删除
【问题描述】
小明是一个完美主义者,现在他的手上有两个只包含小写字母的字符串。
他希望能够使得这两个字符串变得完美,两个字符串完美指的是这两个字符串的长度和每个位置上的字母都相同。
可是他还有一个完美信条:他每次只能删除某一个字符串最左侧的一个字母。
现在他想知道他最少需要删除几个字母能够使这两个字符串变得完美。(两个空串也被认为是完美的)
【输入格式】
在两行中分别给出初始时候的两个字符串,只包含小写字母。
(字符串的长度为1到2e5)
【输出格式】
在一行中输出一个整数表示小明最少需要删除的字母个数
【例子】
a = input()
b = input()
res = 0
la = len(a)
lb = len(b)
sum = la + lb
if la > lb:
for i in range(lb - 1, -1, -1):
la = la - 1
if b[i] == a[la]:
res = res + 1
else:
break
res = sum - 2 * res
print(res)
else:
for i in range(la - 1, -1, -1):
lb = lb - 1
if a[i] == b[lb]:
res = res + 1
else:
break
res = sum - 2 * res
print(res)
9. 电梯
【问题描述】
人们住在n层的房子里。ai人 住在房子的第i层。每个人每天使用电梯两次:从他/她住的楼层到一楼(一楼),晚上回家时从一楼到他/她住的楼层。
在不使用电梯时,电梯停在x层,但x尚未选定。当一个人需要从a层到b层时,电梯遵循简单的算法:
从第x层(最初停留在第x层)移动到第a层并带走乘客。
从a层移动到b层并释放乘客(如果a等于b,电梯只打开和关闭门,但仍然从x层到达a楼层)。
从第b层移回第x层。
电梯从不转载多人,总是在转载下一位乘客之前回到x层。电梯在相邻楼层之间的移动需要消耗一个单位的电力。所以从a层到b层需要| a−b |单位的电力。
你的任务是帮助努特找到最少的电力单位数量,这将是足够的一天,通过选择一个最佳的x层。别忘了电梯最初是停在x层的。
【输入格式】
第一行包含一个整数n(1≤n≤100)-楼层数。
第二行包含n个整数a1,a2,…,an(0≤ai≤100)-每个楼层的人数。
【输出格式】
在一行中,打印问题的答案-最小电力单位数。
【例子】
n = int(input())
a = [1] + [int(x) for x in input().strip().split(' ')]
res = 0
power = []
for i in range(1, n+1):
for j in range(1, n+1):
if j > i:
res = a[j] * ((j-i)*2+(j-1)*2) * 2 + res
else:
res = a[j] * (j-1)*2 * 2 + res
power.append(res)
res = 0
ans = min(power)
print(ans)
10. 奖励(此题耗费时间较长)
【问题描述】
有n个奖励在数轴上。每个奖励的位置各不相同,都是整数坐标。
一开始,你在1的位置上,你的朋友在106的位置上,其他n个奖励在1到106中间的位置上,人和奖励的位置没有重复。
每一秒,我们可以从x移到x-1或者x+1,你和你的朋友的移动速度是一样的。
现在,问你最少需要多少时间,你和你的朋友才能把所有的奖励都拿走。假设你们经过这个奖励的时候,就可以获得这个奖励。获得奖励不需要消耗时间。
【输入格式】
输入第一行是一个正整数n,表示奖励的数量。
接下来n个整数,表示每个奖励的位置,按照递增的顺序给出。
范围都在1到10^6之间。
【输出格式】
输出获取所有奖励需要的最少时间。
【例子】
第一个样例,你把所有的奖励都拿了。
第二个样例,你拿第一个奖励,你朋友拿第二个奖励。
n = int(input())
a = [int(x) for x in input().strip().split(' ')]
friend = 1000000
me = 0
for i in a:
if i <= 500000: #小于不行,要小于等于
if i > me:
me = i
else:
if friend > i:
friend = i
ans = me - 1
if ans < 1000000-friend:
ans = 1000000-friend
print(ans)
11. 字符串相除
【问题描述】
我们定义一个字符串a乘一个数字x,即a*x表示将a这个字符串重复x遍,比"abc"*2=“abcabc”,“a”*5=“aaaaa”。
我们称一个字符串a能被另一个字符串b整除,当且仅当存在一个整数x使得bx=a。比如,"abababab"能被"ab"整除,但不能被"ababab"或者"aa"整除。
接下来我们定义两个字符串s与t的LCM,记为LCM(s,t),为一个能够同时被s与t整除的最短非空字符串。
现在给定字符串s与字符串t,求LCM(s,t)。如果不存在请输出-1。可以证明若LCM(s,t)存在,则其唯一.
【输入格式】
第一行只有一个正整数q(1<=q <=2000)表示数据组数。
每一组数据包含两行字符串s与t(1<=|s|,|t|<=20)。s与t只由字符’a’或字符’b’组成。
【输出格式】
对每组数据,若LCM(s,t)存在,输出LCM(s,t),若不存在,输出-1。
【例子】
import math
def LCM(s,t):
x = list(s)
y = list(t)
xl = len(x)
yl = len(y)
gys = math.gcd(xl,yl) #最小公约数
gbs = int(xl*yl/gys) #最小公倍数
for i in range(int(gbs/xl-1)):
x.extend(s)
for i in range(int(gbs/yl-1)):
y.extend(t)
if x == y:
return ''.join(x) #列表转化为字符串
else:
return -1
n = int(input())
res = []
for i in range(n):
s = list(input())
t = list(input())
res.append(LCM(s,t))
for i in res:
print(i)
12. 线上的点
【问题描述】
直线上多个点集的直径是该集两点之间的最大距离。例如,多重集{1, 3, 2, 1}的直径是2。
由一个点组成的多重集的直径为0。
你在这条线上得了n分。为了使剩余点的多重集的直径不超过d,您必须移除的点的最小数量是多少?
【输入格式】
第一行包含两个整数n和d(1 ≤ n ≤ 100, 0 ≤ d ≤ 100)-分别是点数和最大允许直径。
第二行包含n个空格分隔的整数(1 ≤ xi ≤ 100)-点的坐标。
【输出格式】
输出单个整数-必须删除的点的最小数量。
【例子】
在第一个测试用例中,最佳策略是移除坐标为4的点。其余的点将具有坐标1和2,因此直径将等于2 - 1 = 1。
在第二个测试用例中,直径等于0,因此不需要删除任何点。
在第三个测试用例中,最佳策略是移除坐标为1、9和10的点。其余的点将具有坐标3、4和6,因此直径将等于6 - 3 = 3。
n, d = (int(x) for x in input().strip().split(' '))
a = [int(x) for x in input().strip().split(' ')]
a.sort()
res = n
out = []
for i in range(n):
for j in range(i, n):
if abs(a[j]-a[i]) <= d:
res = res - 1
out.append(res)
res = n
print(min(out))
13. 相等串(题意未理解,代码测试未通过)
【问题描述】
给你两个由小写英文字母组成字符串s,t。如果s[i…i+|t|-1] = t (|t|表示t的长度),则认为s[i…i+|t|-1] 是t的相等串。现在有q次询问,每次询问你s[L…R]中有多少个不同位置的t的相等串。
【输入格式】
第一行输入三个整数n,m,q,表示s,t的长度和询问次数。(1 <= n,m <= 1000 , 1 <= q <= 1000000)。
第二三行分别给出s,t。
接下来q行,每行输入L,R,表示所要查询的区间。(1 <= L <= R <= n)
【输出格式】
输出q行,表示每次查询的结果。
【例子】
n, m, q = (int(x) for x in input().strip().split(' '))
s = [0] + list(input())
t = list(input())
data = []
for i in range(q):
data = data + [int(x) for x in input().strip().split(' ')]
flag = 0
res = 0
if n < m:
for i in range(q):
print("0")
else:
for k in range(1, q+1):
L = data[2*k-2]
R = data[2*k-1]
if R - L + 1 < m:
print("0")
else:
if R > n-m+1:
R = n-m+2
for g in range(L, R):
for j in range(m):
if s[g + j] == t[j]:
flag = flag + 1
if flag == m:
res = res + 1
flag = 0
else:
flag = 0
break
print(res)
res = 0
二、搜索
1. 回家的路
【问题描述】
一只青蛙在一个数轴上,它现在要从点 1跳到点 n,它每次可以向右跳不超过d个单位。比如,它可以从点x跳到点 x + a,a是一个在1到d之间的整数。特别地,青蛙只能在有百合花的点上停留。保证点 1和点n有百合花。请输出青蛙到达点 n的最小跳跃次数。
【输入格式】
输入第一行包含两个整数n和d (2 ≤ n ≤ 100, 1 ≤ d ≤ n - 1),分别表示青蛙想跳去的点以及一次跳跃的最大距离。
第二行是一个长度为n的字符串s,只包含0和1。字符串s中的字符为1,代表对应位置有百合花;否则没有。输入保证s的第一个字符和最后一个字符等于1。
【输出格式】
如果青蛙能不能到达目的地,输出-1。
否则,输出青蛙到达目的地的最小跳跃次数。
【例子】
n, d = (int(x) for x in input().strip().split(' '))
s = input()
flag = True
res = 0
weizhi = 0
if n-1 <= d:
print("1")
else:
while flag:
weizhi = weizhi + d
if weizhi >= n-1:
res = res + 1
flag = False
else:
for i in range(d):
if s[weizhi] == "1":
break
else:
weizhi = weizhi - 1
if i == d - 1:
res = -2
flag = False
res = res + 1
print(res)
2. 相爱相杀
【问题描述】
在游戏《Nurse Love》中,有个分支剧情是因为B喜欢A,但是A喜欢C所以 A与C被杀掉了!
兔子大惊:“とても怖い!”
“如果游戏中有人互相喜欢就好了”兔子这样想着,可是游戏里面没有任何一个人和另一个人互相喜欢,要么是没有喜欢的人,要么是喜欢的人喜欢着别人,真是个悲剧!
这样的复杂喜欢形成了love链,如果说A喜欢B,那么B是A直接喜欢的人,这是直接喜欢关系。
而B喜欢C,这样C会与A成为间接怨恨关系,C喜欢D,那么D也会与A成为的间接怨恨关系. A,B,C,D都在一条love链上。
但是如果E喜欢A,E与C、D没有间接怨恨关系。
一个人物会杀掉与她有直接喜欢关系或者间接恩怨关系的人,为了不使得这样的结局出现,兔子进入游戏中,将n个人分在不同的城市里面,这样就不会发生惨案了!
请问至少要需要多少个城市才能使得惨案不发生?
【输入格式】
第一行包含了整数 n (1 ≤ n ≤ 2000) 代表游戏中人物个数。
接下来的 n 行包含了整数 lovei (1 ≤ lovei ≤ n 或 lovei = -1)。每一个 lovei 表示第 i 个角色喜欢的人。如果 lovei 是 -1,则意味着第 i 个角色没有喜欢的人。
数据保证:没有人会自己喜欢自己 (lovei ≠ i)。同时,不会出现A喜欢B,B喜欢C,C喜欢A的循环情况
【输出格式】
打印一个唯一的整数,代表兔子需要的城市最小个数
【例子】
n = int(input())
a = []
for i in range(n):
x = int(input())
a.append(x)
maxcount = 1
for i in range(n):
if a[i] != -1:
j = i
count = 0
while j >= 0:
j = a[j] - 1 #i是从0开始,所以-1
count+=1
maxcount = max(count, maxcount)
print(maxcount)
找到最长的关系链即可
3. 狼和羊
【问题描述】
Bob是一个农场主 他有一个大大的农场 他养了一群羊放在农场里 令人头疼的是 总是有狼想要吃羊 所以他决定买一些牧羊犬来 保护的她的羊 在一个 R * C 的矩阵里 每一个点 只能代表一空地 狼和羊之中的一个 “.” 代表空地; “S”代表羊; “W” 代表狼; 狼可以自由的向上下左右活动(狼可以自由移动 没有限制 只有牧羊犬会限制他) 如果羊在狼的这些方向的话就很危险 牧羊犬的的作用就是要阻止狼去吃羊 所以 Bob经常会把牧羊犬(“D”)放在羊的前方来阻止狼的靠近; Bob 非常有钱 他可以买很多只牧羊犬 可以理解为无穷多个牧羊犬
【输入格式】
输入 R和L 代表 矩阵的大小 之后 输入 一个矩阵 “.” 代表空地 “S”代表羊 “W” 代表狼 “D” 代表牧羊犬(初始状态下并不会有牧羊犬存在)
【输出格式】
如果不能保护所有的羊输出“No” 否则输出“Yes” 然后输出你的方案 方案有任意多种 输入一种计即可
【例子】
r, l = (int(x) for x in input().strip().split(' '))
a = []
a4 = list("." * (l+2))
a.append(a4)
for i in range(r):
a1 = "." + input() + "."
a2 = list(a1)
a.append(a2)
a.append(a4)
r = r+2
l = l+2
flag = True
for i in range(1, r-1):
for j in range(1, l-1):
if a[i][j] == "S":
if a[i-1][j] == "W" or a[i+1][j] == "W" or a[i][j-1] == "W" or a[i][j+1] == "W":
flag = False
if flag == True:
print("Yes")
for i in range(1, r-1):
for j in range(1, l-1):
if a[i][j] == ".":
a[i][j] = "D"
for i in range(1, r-1):
a[i].pop(0)
a[i].pop(l-2)
print("".join(a[i]))
else:
print("No")
4. 任务分配
【问题描述】
X_X_X又骑电瓶车去兜风了,但是集训队需要安排任务,于是他随机找一个打工仔分配了任务。被分配了任务的人可能在忙,于是又找到了他的打工仔… 现在有n个队员,编号1~n。 1号是X_X_X,2~n号分别是编号a[i]的打工仔。 n号队员想知道X_X_X的任务是怎么落到自己头上来的。
【输入格式】
给出n(1<=n<=2e5),和n-1个数字,代表a[2] ~ a[n],即每个人是谁的打工仔
【输出格式】
输出任务的传递过程
【例子】
#本题答案
n = int(input())
a = [0] + [0] + [int(x) for x in input().strip().split()]
b = []
while a[n] >= 1:
b.append(n)
n = a[n]
b.append(1)
b.reverse()
b_new = (str(x) for x in b) #将列表中的整形转化为字符串
print(" ".join(b_new)) #"".join()只能在列表中含有字符串时使用
#非本题答案,这代码是找出最长的传递链并显示出来
n = int(input())
a = [0] + [0] + [int(x) for x in input().strip().split()]
b = []
mmax = 0
maxcount = 1
for i in range(2, n+1):
if a[i] != 1:
j = i
m = j
count = 0
while a[j] >= 1:
j = a[j]
count+=1
if maxcount < count:
mmax = m
maxcount = count
while a[mmax] >= 1:
b.append(mmax)
mmax = a[mmax]
b.append(1)
b.reverse()
b_new = (str(x) for x in b)
print(" ".join(b_new))
5. 直线世界
【问题描述】
“直线世界”的新年正在到来!在这个世界中,有 n 个单元格,被编号为从 1 到 n 的整数,成为一个 1 × n 的棋盘。人们生活在单元格中。然而,难以在不同单元格之间移动,因为逃离单元格具有难度。人们想与生活在其它单元格中的其他人相遇。
因此,用户 tncks0121 制作了一套在这些单元格之间移动的运输系统,来庆祝新年。首先,他考虑了 n - 1 个正整数 a1, a2, …, an - 1 。对于每个整数 i (其中 1 ≤ i ≤ n - 1),满足条件 1 ≤ ai ≤ n - i 。其次,他制作了 n - 1 个传送门,使用从 1 到 n - 1 的整数编号。第 i (1 ≤ i ≤ n - 1) 个传送门连接了单元格 i 和单元格 (i + ai),并且一个人可以使用第 i 个传送门,从单元格 i 出发,旅行到单元格 (i + ai) 。不幸的是,一个人不能反向使用传送门,这意味着不能使用第 i 个传送门,从单元格 (i + ai) 移向单元格 i 。这是显而易见的,因为存在条件 1 ≤ ai ≤ n - i ,一个人不允许使用传送门离开“直线世界”。
当前,我站在单元格 1 处,并且我想前往单元格 t 。然而,我不知道是否可能抵达那里。请判断,通过使用已建造的运输系统,我是否能够前往单元格 t 。
【输入格式】
第一行包含了两个以空格分隔的整数 n (3 ≤ n ≤ 3 × 104) 和 t (2 ≤ t ≤ n) — 表示单元格的数目,以及我想要前往的目标单元格的索引。
第二行包含 n - 1 个以空格分隔的整数 a1, a2, …, an - 1 (1 ≤ ai ≤ n - i)。数据保证:使用给定的运输系统,一个人无法离开“直线世界”。
【输出格式】
如果我能够使用此运输系统前往单元格 t ,则打印 “YES”。否则,打印 “NO”。
【例子】
n, t = (int(x) for x in input().strip().split(" "))
a = [0] + [int(x) for x in input().strip().split(" ")]
out = [1]
j = 1
while j < n:
j = j + a[j]
out.append(j)
if t in out:
print("YES")
else:
print("NO")
6. 徽章
【问题描述】
在海初,如果一个学生表现的不好老师就会在他的徽章上挖一个洞。今天一位老师逮到了 n名学生又在搞恶作剧。
假设这些学生从1 到 n 分别被编号。 老师先逮到了a学生然后在他的徽章上挖了个洞。 但是这个学生说带头的是另一个学生p_a .
于是老师又抓住学生p_a 在他的徽章上也打了个洞。这个学生又说其实是学生p_{p_a}在恶作剧。
老师挖了好一会儿的洞,不过因为这些学生是有限的,最后老师抓住了一个徽章上已经有一个洞的学生。
在给这个倒霉孩子的徽章上又挖了个洞以后,老师觉得有点累需要蒸个桑拿于是他就不再继续了。
你不知道谁是老师逮到的第一个学生。但是你知道所有的数字 p_i。你的任务是找出每一个a,如果第一个被逮到的学生是a,谁会是徽章上面有两个洞的学生。
【输入格式】
第一行只有一个数字 n (1 <= n <=1000) 是所有调皮的孩子的总数。
第二行有n个数字,从 p_1, …, p_n (1<= p_i <= n), p_i表示这个学生是被学生 i 诬陷的。
【输出格式】
对每一个从1 到 n之间可能的学生 a(a是第一个被抓到的学生) ,打印出谁会是徽章上面有两个洞的学生。
【例子】
n = int(input())
a1 = [0] + [int(x) for x in input().strip().split(" ")]
out = []
for i in range(1, n+1):
a = a1.copy()
j = a[i]
# k = a[j]
a[i] = 0
while a[j] != 0:
k = a[j]
a[j] = 0
j = k
out.append(j)
out1 = [str(x) for x in out]
print(" ".join(out1))
三、二分+前缀和+双指针(尺取法)
1. 二分查找(一)
【问题描述】
蒜头君手上有个长度为 n 的数组 A。由于数组实在太大了,所以蒜头君也不知道数组里面有什么数字,所以蒜头君会经常询问整数 x 是否在数组A 中。
【输入格式】
第一行输入两个整数 n 和 m,分别表示数组的长度和查询的次数。
接下来一行有 n 个整数 ai。
接下来 m 行,每行有 1 个整数 x,表示蒜头君询问的整数。
【输出格式】
对于每次查询,如果可以找到,输出"YES",否则输出"NO"。
【例子】
n, m = (int(x) for x in input().strip().split(" "))
a = [int(x) for x in input().strip().split(" ")]
b = []
for i in range(m):
c = int(input())
b.append(c)
a.sort()
def f_search(data, FindNumber):
first = 0
last = len(data) - 1
while first <= last:
mid = (first + last)//2
if data[mid] == FindNumber:
return True
elif data[mid] > FindNumber:
last = mid - 1
else:
first = mid + 1
return False
for i in range(m):
c = f_search(a, b[i])
if c == True:
print("YES")
else:
print("NO")
2. 二分查找(三)
【问题描述】
蒜头君手上有个长度为 n 的数组 A。由于数组实在太大了,所以蒜头君也不知道数组里面有什么数字,所以蒜头君会经常询问在数组 A 中,比 x 大的最小值是多大?但是这次蒜头君要求这个数字必须大于 x,不能等于 x。
【输入格式】
第一行输入两个整数 n 和 m,分别表示数组的长度和查询的次数。
接下来一行有 n 个整数 ai。
接下来 m 行,每行有 1 个整数 x,表示蒜头君询问的整数。
【输出格式】
对于每次查询,如果可以找到,输出这个整数。
否则输出 −1。
【例子】
n, m = (int(x) for x in input().strip().split(" "))
a = [int(x) for x in input().strip().split(" ")]
b = []
for i in range(m):
c = int(input())
b.append(c)
a.sort()
def f_search(data, number):
first = 0
last = len(data) - 1
while first <= last:
mid = (first + last) // 2
if a[mid] == number:
return mid
elif a[mid] > number:
last = mid - 1
else:
first = mid + 1
return mid
for i in range(m):
if b[i] >= a[n-1]:
print("-1")
else:
d = f_search(a, b[i])
while b[i] >= a[d]:
d+=1
print(a[d])
3. 二分查找(六)
【问题描述】
蒜头君手上有个长度为 n 的数组 A。由于数组实在太大了,所以蒜头君也不知道数组里面有什么数字,所以蒜头君会经常询问在数组 A 中,比 x 小的最大值是多大?但是这次蒜头君要求这个数字必须小于 x,不能等于 x。
【输入格式】
第一行输入两个整数 n 和 m,分别表示数组的长度和查询的次数。
接下来一行有 n 个整数 ai。
接下来 m 行,每行有 1 个整数 x,表示蒜头君询问的整数。
【输出格式】
对于每次查询,如果可以找到,输出这个整数。
否则输出 −1。
【例子】
n, m = (int(x) for x in input().strip().split(" "))
a = [int(x) for x in input().strip().split(" ")]
b = []
for i in range(m):
c = int(input())
b.append(c)
a.sort()
def f_search(data, number):
first = 0
last = len(data) - 1
while first <= last:
mid = (first + last) // 2
if data[mid] == number:
return mid
elif data[mid] > number:
last = mid - 1
else:
first = mid + 1
return mid
for i in range(m):
if b[i] <= a[0]:
print("-1")
else:
d = f_search(a, b[i])
while a[d] >= b[i]:
d-=1
print(a[d])
4. 前缀极差
【问题描述】
蒜头君有 n 个数,他提出了 q 个问题,每个问题是说,询问前 x 个数的极差(最大值减最小值)。你能帮助他解决这 q 个问题吗?
【输入格式】
【输出格式】
输出一行,包含 q 个整数,表示每一次询问的答案
【例子】
#此代码不行,超时
n, q = (int(x) for x in input().strip().split(" "))
a = [int(x) for x in input().strip().split(" ")]
x1 = [int(x) for x in input().strip().split(" ")]
out = []
b = []
for i in range(q):
c = x1[i]
for j in range(i+1):
e = a[j]
b.append(e)
b.sort()
bMax = b[i]
bMin = b[0]
cha = bMax - bMin
out.append(cha)
b.clear()
out1 = [str(x) for x in out]
print(" ".join(out1))
n, q = (int(x) for x in input().strip().split(" "))
a = [int(x) for x in input().strip().split(" ")]
x1 = [int(x) for x in input().strip().split(" ")]
Max = []
Min = []
for i in range(q):
5. number of ways
【问题描述】
五校新生欢乐赛终于开始了,我们ACMer的老学长早就兴奋坏了,我们这里有n个老学长早就抱着可乐看戏了,他们每个人只有一个能喝的可乐数量,第i个人能喝的最大可乐数量用a[i]表示,这些学长已经按照顺序坐好了,我们想知道有多少种分配方式把这些学长分为三个区域,使这三个区域学长喝的总可乐量都相等。
即问有多少个点对(i,j)满足a[1]+…+a[i-1]=a[i]+a[i+1]+…+a[j]=a[j+1]+a[j+2]+…+a[n]
【输入格式】
第一行一个整数n表示学长人数。(1<=n<=5*10^5)
第二行n个整数分别表示每个学长能喝的可乐数量。(|a[i]|<=10^9)
【输出格式】
输出一个整数表示答案。
【例子】
n = int(input())
a = [int(x) for x in input().split(" ")]
sun = [0]
b = a[0]
sun.append(b)
res = 0
c = 0
for i in range(1, n):
b = a[i] + b
sun.append(b)
if sun[n] % 3 != 0:
print(0)
else:
d = sun[n] / 3
e = 2 * d
for i in range(1, n):
if sun[i] == e:
res += c
if sun[i] == d:
c+=1
print(res)
6. sj学姐
【问题描述】
sj学姐发现自己的裙子上有一个由n个数组成的数组,恰巧sj学姐的幸运数字是s,sj学姐想求出总和不小于s的子数组长度的最小值,但sj学姐太忙了,帮sj学姐解决这个问题。
【输入格式】
最开始一行m,表示测试样例的数目
每个测试样例的第一行输入n(1<n<=100000)和s(1<s<=100000000),第二行输入n个正整数。
【输出格式】
找到满足要求的连续子数组的最小长度,如果没有,输出0。
【例子】
#程序测试中未有python选项,未进行代码测试
def f(n, s, data):
res = n + 1
sun = 0
L = -1
R = -1
while True:
while R < n-1 and sun < s:
R += 1
sun += data[R]
if sun < s:
break
res = min(res, R-L)
L += 1
sun -= data[L]
if res > n:
res = 0
return res
out = []
m = int(input())
for i in range(m):
n, s = (int(x) for x in input().split(" "))
a = [int(x) for x in input().split(" ")]
b = f(n,s,a)
out.append(b)
for i in out:
print(i)
7. 连续序列(不容易啊)
【问题描述】
从数列中找出连续序列,使得和的绝对值与目标数之差最小
【输入格式】
多组用例,每组用例
第一行两个整数n和m分别表示数列长度和查询次数,
第二行为n个整数表示数列,
第三行为m个整数表示目标数,以n=k=0结束输入 0<=t<=1000000000;1<=n<=100000
【输出格式】
对于每次查询,输出三个整数sum,l,r,分别表示其绝对值与目标数之差最小的连续序列值与此连续序列的左右端点
【例子】
#程序测试中未有python选项,未进行代码测试
def f(n,t, data):
b = 0
c = []
d = []
L = 0
R = 1
RD = 0
LD = 0
out = []
for i in range(0, n+1):
b += data[i]
c.append(b)
e = str(i)
d.append(e)
g = list(zip(c, d))
g.sort()
Min = float("inf")
while R < n+1 and L < R:
res = g[R][0] - g[L][0]
if abs(abs(res - t)) <= Min:
RD = max(int(g[R][1]), int(g[L][1]))
LD = min(int(g[R][1]), int(g[L][1]))+1
Min = abs(abs(res - t))
# ans = res
if res < t:
R += 1
elif res == t:
break
else:
L += 1
out.append(res)
out.append(LD)
out.append(RD)
return out
chu = []
while True:
n, m = (int(x) for x in input().split(" "))
if n == 0 and m == 0:
break
else:
a = [0] + [int(x) for x in input().split(" ")]
mubiao = [int(x) for x in input().split(" ")]
for i in range(m):
b = f(n, mubiao[i], a)
chu.append(b)
for i in chu:
z = [str(x) for x in i]
print(" ".join(z))
四、贪心
1. 外币兑换
【问题描述】
蒜头君刚从美国回来,发现手上还有一些未用完的美金,于是想去银行兑换成人民币。可是听说最近人民币将会升值,并从金融机构得到了接下来十二个月可能的美元对人民币汇率,现在,蒜头君想要在接下来一年中把美金都兑换成人民币,请问最多能得到多少人民币?
【输入格式】
【输出格式】
输出一个小数 R,表示蒜头君最多能获得的人民币数量,结果保留两位小数。
【例子】
n = float(input())
a = [float(x) for x in input().split()]
a_max = max(a)
sun = a_max * n
print(round(sun,2))
2. 今年暑假不AC
【问题描述】
“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%…”
确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
【输入格式】
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
【输出格式】
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
【例子】
#程序测试中未有python选项,未进行代码测试
n = int(input())
t_s = []
t_e = []
t = []
res = 1
for i in range(n):
x, y = (int(j) for j in input().split(" "))
t_s.append(str(x))
t_e.append(y)
t = list(zip(t_e,t_s))
t.sort()
tt = 0
tte = t[0][0]
tts = int(t[0][1])
for i in range(1, n):
if int(t[i][1]) >= tte:
tte = t[i][0]
res += 1
print(res)
3. 混合牛奶
【问题描述】
由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要。帮助 Marry 乳业找到最优的牛奶采购方案。
Marry 乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是不同的。此外,就像每头奶牛每天只能挤出固定数量的奶,每位奶农每天能提供的牛奶数量是一定的。每天 Marry 乳业可以从奶农手中采购到小于或者等于奶农最大产量的整数数量的牛奶。
给出 Marry 乳业每天对牛奶的需求量,还有每位奶农提供的牛奶单价和产量。计算采购足够数量的牛奶所需的最小花费。
注:每天所有奶农的总产量大于 Marry 乳业的需求量。
【输入格式】
【输出格式】
单独的一行包含单独的一个整数,表示 Marry 的牛奶制造公司拿到所需的牛奶所要的最小费用。
【例子】
n, m = (int(x) for x in input().split(" "))
p = []
for i in range(m):
a =[int(x) for x in input().split(" ")]
p.append(a)
p.sort()
sun = 0
j = 0
money = 0
while sun < n:
sun += p[j][1]
money += p[j][0]*p[j][1]
j += 1
j = j - 1
duo = sun - n
money = money - p[j][0]*duo
print(money)
4. 最小距离字符串
【问题描述】
【输入格式】
输入有三行,每行一个字符串,分别为 A,B,C,保证他们都是非空的小写字母字符串,且长度都相同。字符串长度不超过 2×100000。
【输出格式】
【例子】
a = input()
b = input()
c = input()
l = len(a)
res = 0
for i in range(l):
if a[i] == b[i] and a[i] == c[i]:
res += 0
elif a[i] != b[i] and a[i] != c[i] and b[i] != c[i]:
res += 2
else:
res += 1
print(res)
5. 轻重搭配(普通方法超时)
【问题描述】
n 个同学去动物园参观,原本每人都需要买一张门票,但售票处推出了一个优惠活动,一个体重为 x 的人可以和体重至少为 2x 配对,这样两人只需买一张票。现在给出了 n 个人的体重,请你计算他们最少需要买几张门票?
【输入格式】
第一行一个整数 n,表示人数。
第二行 n 个整数,每个整数 ai 表示每个人的体重。
【输出格式】
一个整数,表示最少需要购买的门票数目。
【例子】
n = int(input())
a = [int(x) for x in input().split(" ")]
a.sort()
num = 0
j = n-1
t = n // 2 - 1
while t >= 0:
if 2*a[t] <= a[j]:
num += 1
t -= 1
j -= 1
else:
t -= 1
print(n-num)
6. 纪念品分组
【问题描述】
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
【输入格式】
【输出格式】
包含一个整数,即最少的分组数目。
【例子】
w = int(input())
n = int(input())
m = []
for i in range(n):
money = int(input())
m.append(money)
m.sort()
num = 0
j = n-1
k = 0
while j > k:
if m[k]+m[j] <= w:
k += 1
j -= 1
num += 1
else:
j -= 1
print(n-num)
五、dp
1. To the Max
【问题描述】
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
的最大子矩阵是
9 2
-4 1
-1 8
这个子矩阵的大小是15。
【输入格式】
输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[-127, 127]。
【输出格式】
输出最大子矩阵的大小。
【例子】
a = []
L = 0
n = int(input())
while L < n*n:
b = [int(x) for x in input().split(" ")]
a = a + b
L = len(a)
print(a)
ha = [0] * n
c = []
c.append(ha.copy())
ha.clear()
j = 0
for i in range(1, n+1):
while j < i*n:
ha.append(a[j])
j += 1
c.append(ha.copy())
ha.clear()
print(c)
for i in range(n):
for j in range(1, n+1):
c[j][i] = c[j][i] + c[j-1][i]
print(c)
res = 0
for j in range(0, n):
for k in range(j+1, n+1):
tmp = 0
for i in range(n):
tmp = c[k][i] - c[j][i] + tmp
if tmp <= 0:
tmp = 0
else:
if tmp > res:
res = tmp
print(res)
#可以找出该矩阵的位置
a = []
L = 0
n = int(input())
while L < n*n:
b = [int(x) for x in input().split(" ")]
a = a + b
L = len(a)
print(a)
ha = [0] * n
c = []
c.append(ha.copy())
ha.clear()
j = 0
for i in range(1, n+1):
while j < i*n:
ha.append(a[j])
j += 1
c.append(ha.copy())
ha.clear()
print(c)
for i in range(n):
for j in range(1, n+1):
c[j][i] = c[j][i] + c[j-1][i]
print(c)
res = 0
for j in range(0, n):
for k in range(j+1, n+1):
tmp = 0
hhs = 1
for i in range(n):
tmp = c[k][i] - c[j][i] + tmp
if tmp <= 0:
tmp = 0
hhs = i+2
else:
if tmp >= res:
ls = j+1
le = k
hs = hhs
he = i+1
res = tmp
print(res,ls,le,hs,he)
2. 恰鸡
【问题描述】
木辰一直痴迷于恰鸡。但是他总是喜欢送快递,因为他知道“穷吃鸡,富快递”,他想做个富人!现在房间有n个配件,每个配件的重量是m价值是v。木辰发现了一个3级包,他可太兴奋了!三级包容量为s,所以木辰最多能当多肥的快递员呢?
【输入格式】
输入的第一行是T, 表示有一共要打T场比赛.
每组数据由三行组成.
第1行包含两个整数n和s 第2行包含n个整数, 表示每一个配件的价值. 第3行包含n个整数, 表示每个配件的重量.
【输出格式】
对每一组数据, 输出木辰可以多肥(此数字将小于 231).
【例子】
在这里插入代码片
3. 老鼠的速度与体重
【问题描述】
很多肥老鼠认为,长的越肥,奔跑速度就越快,为了反驳这个观点,你现在需要对老鼠的体重和速度进行研究,你要在老鼠序列中找出一个子序列,使得老鼠的体重在增加,但是速度却在减慢
【输入格式】
输入以eof结束。
输入中每行有两个正整数,分别表示老鼠的体重和速度,范围均在1到10000之间,输入数据最多有1000只老鼠。
某些老鼠可能有相同的体重,某些老鼠可能有相同的速度,某些老鼠可能体重和速度都相同。
【输出格式】
程序应该输出一系列数据行;第一行应该包含一个数字n;其余n行应该每个包含一个正整数(每个代表一只老鼠)。如果这n个整数是m[1],m[2],…,m[n],那么一定是
W[m[1]] < W[m[2]] < … < W[m[n]]
and
S[m[1]] > S[m[2]] > … > S[m[n]]
为了使答案正确,n应该尽可能大。
所有的不等式都是严格的:权重必须严格递增,速度必须严格递减。对于给定的输入,可能有许多正确的输出,程序只需要找到其中一个
【例子】
4. 猴子和香蕉
【问题描述】
一组研究人员正在设计一项实验,以测试猴子的智商。他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子。如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉。
研究人员有n种类型的砖块,每种类型的砖块都有无限个。第i块砖块的长宽高分别用xi,yi,zi来表示。 同时,由于砖块是可以旋转的,每个砖块的3条边可以组成6种不同的长宽高。
在构建塔时,当且仅当A砖块的长和宽都分别小于B砖块的长和宽时,A砖块才能放到B砖块的上面,因为必须留有一些空间让猴子来踩。
你的任务是编写一个程序,计算猴子们最高可以堆出的砖块们的高度。
【输入格式】
输入文件包含多组测试数据。
每个测试用例的第一行包含一个整数n,代表不同种类的砖块数目。n<=30.
接下来n行,每行3个数,分别表示砖块的长宽高。
当n= 0的时候,无需输出任何答案,测试结束。
【输出格式】
对于每组测试数据,输出最大高度。格式:Case 第几组数据: maximum height = 最大高度
【例子】
5. 伊格纳修斯和公主
【问题描述】
给出n个数,zjm想找出出现至少(n+1)/2次的数, 现在需要你帮忙找出这个数是多少?
【输入格式】
本题包含多组数据:
每组数据包含两行。
第一行一个数字N(1<=N<=999999) ,保证N为奇数。
第二行为N个用空格隔开的整数。
数据以EOF结束。
【输出格式】
对于每一组数据,你需要输出你找到的唯一的数。
【例子】
在这里插入代码片
6. 通信系统
【问题描述】
NUPT要建立一套系统,该系统需要n种设备,而每种设备分别可以有m1、m2、m3、…、mn个厂家提供生产,而每个厂家生产的同种设备都会存在两个方面的差别:参数和 价格。
现在每种设备都各需要1个,考虑到性价比问题,要求所挑选出来的n件设备,要使得F/P最大。其中F为这n件设备的参数的最小值,P为这n件设备的总价。我们的目标是为每个设备选择一个制造商来最大化F / P。
【输入格式】
输入文件的第一行包含一个整数t(1≤t≤10)表示t组测试样例。每个测试样例包含单个整数n(1≤n≤100)表示系统中的设备数,后面以下的n行包含:第i行(1≤i≤n)第一个数为制造商的设备数量mi(1≤mi≤100),之后是mi对正整数,分别表示制造商对应的参数和价格。
【输出格式】
每个测试样例只包含一个数,为F / P的最大值并保留3位有效小数。
【例子】
在这里插入代码片
模拟一
A. 6的个数
b = 0
for i in range(1, 2022):
a = list(str(i))
b = a.count("6") + b
a.clear()
print(b) #602
B. 小明的作业
a = input()
b = list(a)
c = len(b)
print(c)
jing = 0
cuo = 0
flag = False
for i in range(c-3):
if b[i] == "w" and b[i+1] =="a":
j = i + 2
b[i] = "M"
b[i+1] = "M"
while b[j] == "w" and b[j+1] =="a":
b[j] = "M"
b[j+1] = "M"
j = j + 2
flag = True
if flag == True:
cuo += 1
flag = False
else:
jing += 1
if b[i] == "a" and b[i + 1] == "w":
j = i + 2
b[i] = "M"
b[i + 1] = "M"
while b[j] == "a" and b[j + 1] == "w":
b[j] = "M"
b[j + 1] = "M"
j = j + 2
flag = True
if flag == True:
cuo += 1
flag = False
else:
jing += 1
print(b)
print(jing)
print(cuo)
C. 斐波那契
from fractions import Fraction
nun = [0]
num1 = 1
num2 = 1
nun.append(num1)
nun.append(num2)
res = 0
for i in range(1, 14):
a = nun[i] + nun[i+1]
nun.append(a)
for i in range(1, 14):
res = res + 1/(nun[i]*nun[i+1])
print(Fraction(res).limit_denominator())
D.数组重组
在这里插入代码片
E.三角形个数
ans = ((n+1)*(2*n*n+3*n-1)//8)%(10**9+7)
print(ans)
F.字符串
【问题描述】
【输入格式】
【输出格式】
【例子】
n = int(input())
res = 0
for i in range(n):
a = input()
if "@wyk" in a:
res += 1
print(res)
G. 最大子矩阵
F. 友谊纽带
在这里插入代码片
1. **
【问题描述】
【输入格式】
【输出格式】
【例子】