1.游乐园
题目
游乐园玩碰碰车,其中有一种碰碰车是在一条直线上行驶。该碰碰车有一个初始朝向和初始位置,并且以每秒一个单位的速度向初始方向前行,当它和其它碰碰车相遇时,它们会立刻掉头(由于速度很快,掉头时间可以忽略)。你可以算出它们在t秒后的位置吗?
格式:
输入格式:
第一行有两个数字n(1-1000),t(0-1000),分别表示:碰碰车的数量和所用时间:
接下来n行,每一行都有两个数字:x,f分别表示第n辆碰碰车的位置和方向
(0<x≤105,-1表示向左,1表示向右)。
输出格式:
输出行,每一行两个数字,分别表示碰碰车最后的位置和方向
(-1表示向左,1表示向右,0表示两车相遇)。
示例:
输入:5 2
4 1
5 -1
7 1
2 1
6 -1
输出:4 0
4 0
9 1
3 -1
6 1
结果
class CAR ():
def __init__(self,x=None,f=None,ID=None):
self.x = x
self.f = f
self.ID = ID
n,t = map(int,input().split())
car = [CAR() for i in range(n)]
for i in range(n):
car[i].x,car[i].f = map(int,input().split())
car[i].ID = i+1
# 不用建立id列表的话直接用carTemp[i].ID赋值的话,会错误(不知道为啥)
id = []
carTemp=sorted(car,key= lambda car:car.x)
for i in range(n):
id.append(carTemp[i].ID)
for i in range(n):
car[i].x=car[i].x+car[i].f*t
car.sort(key=lambda car:car.x)
for i in range(n):
car[i].ID = id[i]
if i>0 and car[i].x==car[i-1].x or i<n-1 and car[i].x==car[i+1].x:
car[i].f = 0
car.sort(key=lambda car:car.ID)
for i in range(n):
print(car[i].x,car[i].f)
2.三合一
题目
有一个数组,每一个位置有一个1-9的数,现对其进行三合一操作
三合一操作有若干轮:每一轮,从前往后扫,如果三个相邻的数的和小于等于“轮次*3”,则这三个数合并为一个数。如果能合,本轮的下一次扫描就从三个数后面的第一个数开始扫;如果不能合,就从这三个数的第二个数开始扫。他们相加的和经过有限轮后,该数组肯定会变为一个数或两个数。
现在需要你求出一共进行了多少轮(没有进行任何操作的轮次也算)。
格式
输入格式:第一行一个整数n
第二行n个整数
输出格式:一行一个整数,表示进行了多少轮
示例
输入:3
1 2 3
输出:2
代码
使用链表
class ListNode():
def __init__(self,val,next=None):
self.val=val
self.next=next
class LinkList():
def __init__(self):
self.head = None
def initList(self,data):
self.head = ListNode(data[0])
cur = self.head
pre = self.head
for i in data[1:]:
node = ListNode(i)
pre.next = node
pre = pre.next
return cur
n = int(input())
data = list(map(int,input().split()))
linkList = LinkList()
linkList = linkList.initList(data)
cnt = 0
while linkList.next and linkList.next.next:
cur = linkList
while cur and cur.next and cur.next.next:
cnt += 1
sum = cur.val + cur.next.val + cur.next.next.val
if sum <= cnt*3:
cur.val = sum
cur.next = cur.next.next.next
cur = cur.next
else:
cur = cur.next
print(cnt)
暴力,使用两个list
n = int(input())
a = list(map(int,input().split()))
cnt = 0
while len(a) > 2:
b = [] # 每次循环都清空b列表
le = len(a)
i = 0
while i < le:
if i + 2 < le:
s1 = a[i] + a[i+1] + a[i+2]
if s1 <= (cnt+1)*3:
b.append(s1)
i += 3
else:
b.append(a[i])
i += 1
else:
b.append(a[i])
i += 1
a = b # 循环结束后,重置a列表
cnt += 1
print(cnt)
3.数据流中位数
题目
对于数据流问题,小码哥需要设计一个在线系统,这个系统不断的接受一些数据,并维护这些数据的一些信息。
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
请帮小码哥设计一个支持以下两种操作的系统:
+num --> 从数据流中添加一个整数k到系统中(0<k<232).
?–> 返回目前所有元素的中位数。
格式
输入格式:第一行输入一个整型n(n≤100000)
第二行输入n个操作
输出格式:?询问时输出中位数,每个操作一行,保证每次查询都合法
示例:
输入:
5
+ 1
+ 2
?
+ 3
?
输出:
1.5
2
代码
使用heapq模块建立小根堆,堆头为堆的最小值。如果将内部元素全取负,则成为大根堆,堆头为最大。每次循环,更新大根堆和小根堆,奇数时中位数在大根堆max_heap中。
import heapq
max_heap = []
min_heap = []
n = int(input())
for _ in range(n):
x = input()
if x.startswith('+'):
num = int(x[-1])
# 如果两个堆都为空,或者num小于等于最大堆的根节点(即列表左半部分的最大值),则将num加入最大堆
if not max_heap or num <= -max_heap[0]:
heapq.heappush(max_heap, -num)
else:
# 否则将num加入最小堆
heapq.heappush(min_heap, num)
# 调整两个堆的大小,使其相差不超过1,并且最大堆不小于最小堆
if len(max_heap) > len(min_heap) + 1:
heapq.heappush(min_heap, -heapq.heappop(max_heap))
elif len(min_heap) > len(max_heap):
heapq.heappush(max_heap, -heapq.heappop(min_heap))
else:
# 如果两个堆大小相等,则中位数是两个根节点的平均值
if len(max_heap) == len(min_heap):
mid = (-max_heap[0] + min_heap[0]) / 2
if mid == int(mid): # mid是浮点数,如果是2.0这样的需要转成整数2
mid = int(mid)
else:
# 否则中位数是较大的那个堆的根节点
mid = -max_heap[0]
print(mid)
4.硬币塔
说实话没看懂题目啥意思()
题目
一个k级的硬币塔从下到上,由1个银币,一个k-1级硬币塔,k个金币,一个k-1级硬币塔,1个银币堆成。其中,0级硬币塔只有一个金币。
问:n级硬币塔从下向上数i个有几个金币。
格式
输入格式:一行用空格隔开的两个整数几,i
输出格式:一个整数表示答案
示例
输入:513
输出:6
代码
代码也没看懂。。。
# 计算每一层的硬币个数
def tower(k):
if k == 0:
return 1
return 2+k+2*tower(k-1)
# 计算每一层的金币个数
def count(k):
if k == 0:
return 1
return k+2*count(k-1)
def todo(k,i,res):
if k == 0:
if i>0:
res[0] += 1
return
else:
num = tower(k)
temp = tower(k-1)
if i <= k:
res[0] += 0 # ???这是啥操作
elif i >= num - k:
res[0] += count(k)
elif i > temp + k + 1:
res[0] += count(k-1) + k
todo(k-1,i-temp-k-1,res)
elif i > temp + 1:
res[0] += count(k-1) + i - temp -1
elif i > k:
todo(k-1,i-1,res)
n,i = map(int,input().split())
if i <=n:
print(0)
else:
res = [0]
todo(n,i,res)
print(res[0])
5.最大平均值
题目
给一个数组,长度为n,找一个长度大于等于m的子区间,使这个区间的元素的平均值最大。
格式
输入格式:第一行输入整数n和m,数据间用空格隔开;
接下来n行,每行输入一个整数a:.
输出格式:输出一个整数,表示平均值的最大值乘以1000再向下取整之后得到
的结果。
示例
输入:
10 6
6
4
2
10
3
8
5
9
4
1
输出:
6500
代码
a = []
amax = 0
amin = 1e7
def check_mid(mid,n,m):
sum = [0 for _ in range(n + 1)]
for i in range(1,n + 1):
sum[i] = sum[i-1] +a[i-1]-mid
for i in range(m,n+1):
minn = 0
minn = min(minn,sum[i-m])
if sum[i] > minn:
return True
else:
return False
# 将输入存在列表中
n, m = map(int,input().split())
amax = 0
amin = 1e7
for _ in range(n):
val = float(input())
a.append(val)
if val > amax:
amax = val
if val < amin:
amin = val
while amax > amin + 10e-7:
mid = (amax + amin) / 2.0
if check_mid(mid,n,m):
amin = mid
else:
amax = mid
print(int(1000*amax))
6.括号家族
题目
小码哥在研究只有左括号和右括号组成的序列。给出一个括号序列,求出最长合法子
串和它的数量(合法的定义:这个序列中左右括号匹配)。
例如:(()
合法,)()(
也不合法,但()()
和(())
合法。
格式
输入格式:输入一行只有左括号和右括号组成的序列(只包含小括号)。
输出格式:输出两个数字:最长子字符串的长度,以及此类子字符串的数量,如
果没有这样的子字符串,则输出 0 1
示例
输入:()()))()()(()
输出:4 2
代码
s = input()
def solution(s):
stack = [] # 存放括号的索引
ans = 0 # 记录最长合法子串长度
cnt = 0 # 记录个数
stack.append(-1)
for i in range(len(s)):
if s[i] == '(': # 最开始必须是(,)在最前面无意义
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i)
else:
cur_len = i - stack[-1]
if cur_len > ans: # 长度大于最大长度,重置ans和cnt
ans = cur_len
cnt = 1
elif cur_len == ans: # 等于最大长度,cnt++
cnt += 1
return (ans, cnt)
ans,cnt = solution(s)
if ans == 0:
print('0 1')
else:
print(f'{ans} {cnt}')
杂七杂八(小知识点)
- 一次性建立多个类
采用列表car = [CAR() for i in range(n)]
而不是car = [CAR()]*3
- input()格式转换
input() 函数接受一个标准输入数据,返回为 string 类型。
将其转换为int型可以直接n = int(input())
但如果使用input().split()的话,返回值为列表,不能直接int(列表)转为int格式,应该使用map函数n,t = map(int,input().split())
- sort 和sorted
sort直接修改原列表,无返回值;sorted返回新列表,修改原列表不影响新列表。
# 使用sorted()函数对列表进行排序,返回一个新的列表
sorted_lst = sorted(lst, key=lambda obj: obj.f)
# 使用list.sort()方法对列表进行排序,修改原始列表
lst.sort(key=lambda obj: obj.f)