ccf碰撞的小球python_Python版 CSP目前所有第二题

 Python也太香了2.0。

"题解仅供参考。"

CCF-CSP认证地址:http://cspro.org/

声明:这里的202006-2稀疏向量这道题,找遍了CSDN都没有找到超过60分的Python答案,如果有,可以dd我哈哈,思路很简单,代码是没错的,但最后的测试数据量太大了。

先上一波运行结果

4a921c76166bd53981a0eabcfb7ad422.png

846ccd246c8cd332a1c88e03a09356df.png

e56fdf6816461ac503ed135e6d62d379.png

f563d6c8ecfc7865a239f33dd9e4854e.png

9fecca2a1c135389ed7c1e2c4294de73.png

882f41a94db350fc6a8c74523534d67c.png

ad689baf7a27a783c922a441457626e3.png

ae76b93af53f49c0f76d4b676732e727.png

5dda96a4ae6e7bf39993ff2a65a812af.png

8a8960742f20b5165880c17bd296716f.png

3c92fdd968d9e15ae67dd464e7f2b3e4.png

354baac4ce8eef93ffb64fd1ef7d7f9d.png

a191a87a971c6621cf9a67cb5b01782e.png

8b6f8f973aa5123371e7f7f5bc583995.png

0040e7408cc35944f8228ae97512eea4.png

44a381553982ea921f05aa8ff7b2256c.png

e0c64b587ebb90fabc4a46752371e729.png

625977206a5e53ee783ec7fcfc9e05b6.png

b03a290bb7069eb0db7d3e152409263f.png

cfeebbe0915483a69175fc3ff60500de.png

01

总结

第二题的坑非常多,稍微没考虑到就扣你个四五十的,到时候CSP证都没得拿了。

写的时候要把题目啃多两遍再写,千万不要看到题目感觉懂了就开始写。

很多时候显示错误,但就是不知道哪里错了,很痛苦,一定要善于使用debug。

按照CSP真题顺序贴代码

稀疏向量

def index():    lineOne = [int(item) for item in input().split()]    size1 = lineOne[1]    size2 = lineOne[2]    s = 0    v1 = {}    v2 = {}    for i in range(size1):        ls = [int(item) for item in input().split()]        v1[ls[0]] = ls[1]    for i in range(size2):        ls = [int(item) for item in input().split()]        v2[ls[0]] = ls[1]    v = v1.keys() & v2.keys()    for item in v:        s += v1[item] * v2[item]    print(s)index()

回收站选址

def index():    size = int(input())    zbList = []    levelList = [0 for i in range(5)]    for i in range(size):        ls = [int(item) for item in input().split()]        zbList.append([ls[0], ls[1]])    for zb in zbList:        if is0(zbList, zb[0], zb[1]) == True:            level = getLevel(zbList, zb[0], zb[1])            levelList[level] += 1    for lv in levelList:        print(lv)# 判断是不是0级站点 (上下左右都要有站点)# return True | Falsedef is0(zbList, x, y):    if [x + 1, y] in zbList and [x - 1, y] in zbList and [x, y + 1] in zbList and [x, y - 1] in zbList:        return True    else:        return False# 获取站点的等级# return level(int)def getLevel(zbList, x, y):    level = 0    if [x + 1, y + 1] in zbList:        level += 1    if [x + 1, y - 1] in zbList:        level += 1    if [x - 1, y + 1] in zbList:        level += 1    if [x - 1, y - 1] in zbList:        level += 1    return levelindex()

小明种苹果(续)

def index():    TreeSize = int(input())    delAppleList = []    dropList = [0 for item in range(TreeSize)]  # 记录下掉落苹果的树    T, D, E = 0, 0, 0    for i in range(TreeSize):        ls = list(map(int, input().split()))        delAppleList.append(ls[1:])    for i, item in enumerate(delAppleList):        appleNum = item[0]        for j in range(1, len(item)):            if item[j] <= 0:                appleNum += item[j]            elif appleNum != item[j]:                # 防止同一颗树掉落两次时 掉落苹果的树的总数增加  (小细节)                if dropList[i] != 1:                    dropList[i] = 1                    D += 1                appleNum = item[j]        T += appleNum    if D >= 3:        for i in range(len(dropList)):            prevTree = i - 1            nextTree = i + 1            curTree = i            if nextTree > len(dropList) - 1:                nextTree = 0            if dropList[prevTree] == dropList[curTree] == dropList[nextTree] == 1:                E += 1    print(T, D, E)index()

二十四点

def index():    n = int(input())    retList = []    for i in range(n):        num = eval(input().replace("x", "*").replace("/", "//"))        if num == 24:            retList.append("Yes")        else:            retList.append("No")    for ret in retList:        print(ret)index()

小明放学

def index():    light = [int(item) for item in input().split()]    # 一轮红绿灯的时间    oneTime = sum(light)    # 红黄绿灯的时间    timeDic = dict(zip([1, 2, 3], light))    # 红黄绿灯的下一个灯是什么灯    lightDic = dict(zip([1, 2, 3], [3, 1, 2]))    n = int(input())    lightList = []    for i in range(n):        ls = [int(item) for item in input().split()]        lightList.append(ls)    s = 0    for item in lightList:        if item[0] == 0:            s += item[1]        else:            # 计算此时是什么灯            time = s % oneTime            while time > item[1]:                time -= item[1]                # 更新灯颜色                item[0] = lightDic[item[0]]                # 更新秒数                item[1] = timeDic[item[0]]            item[1] -= time        if item[0] == 1:            s += item[1]        elif item[0] == 2:            s += item[1] + timeDic[lightDic[item[0]]]    print(s)index()

买菜

def index():    n = int(input())    H = []    W = []    # H的装车时间    for i in range(n):        ls = [int(item) for item in input().split()]        for i in range(ls[0], ls[1]):            H.append(i)    # W的装车时间    for i in range(n):        ls = [int(item) for item in input().split()]        for i in range(ls[0], ls[1]):            W.append(i)    # 找出子集    sameTimeList = list(set(H).intersection(set(W)))    print(len(sameTimeList))index()

碰撞的小球

class ball:    def __init__(self, direction, maxDir):        self.direction = direction  # 小球初始位置        self.flag = 1  # 1 向右走  -1 向左走        self.maxDir = maxDir  # 边界    def go(self):        self.direction += self.flag    def changeDir(self):        self.flag = -self.flag    def getDir(self):        return self.direction# 判断两个小球是否碰撞def isCollision(ball1, ball2):    return ball1.getDir() == ball2.getDir()# 判断小球是否到达边缘def isMax(ball):    return ball.getDir() == ball.maxDir or ball.getDir() == 0def index():    lineOne = [int(item) for item in input().split()]    maxDir = lineOne[1]    time = lineOne[2]    ballDirList = [int(item) for item in input().split()]    ballList = []    # 创建 若干个小球    for item in ballDirList:        b = ball(item, maxDir)        ballList.append(b)    # 开始运动 一共运动time秒    for i in range(time):        # 所有小球前进 1 步        for b in ballList:            b.go()        # 判断小球是否到达边缘        for b in ballList:            if isMax(b):                b.changeDir()        # 判断两个小球是否碰撞        for i1 in range(len(ballList)):            for i2 in range(i1, len(ballList)):                if ballList[i1] != ballList[i2]:                    if isCollision(ballList[i1], ballList[i2]):                        ballList[i1].changeDir()                        ballList[i2].changeDir()    for b in ballList:        print("%d " % b.getDir(), end=" ")index()

游戏

def index():    def is2(num, k):        return num % k == 0 or (num - k) % 10 == 0    lineOne = [int(item) for item in input().split()]    childSum = lineOne[0]  # 小朋友总数    k = lineOne[1]  # 报到k的倍数或最后一个数为k的小朋友淘汰    childList = [i + 1 for i in range(childSum)]  # 创建一群小朋友并从1开始赋予编号    num = 1  # 小朋友报到的数    # 如果剩下的小朋友数量 > 1 就一直报数    while len(childList) > 1:        # 从数组中弹出数组中的第一个小朋友        child = childList.pop(0)        # 如果这个小朋友报的数不满足淘汰条件        if is2(num, k) == False:            # 把小朋友重新放到数组的最后一个 进行下一轮报数            childList.append(child)        num += 1    # 执行到这说明小朋友数组里已经只剩1个小朋友  输出这个最后胜利的小朋友    print(childList[0])index()

公共钥匙盒

def index():    N, K = map(int, input().split())    keyList = [i + 1 for i in range(N)]  # 默认钥匙盒    borrowList = []  # 借出记录    for i in range(K):        w, s, c = map(int, input().split())        borrowList.append((w, s, s + c))  # s+c表示归还时间    timeList = []    for item in borrowList:        timeList.append((item[0], item[1], 1))  # 借的时间点  0 钥匙编号  1 借还时间  2 (1表示借)        timeList.append((item[0], item[2], 0))  # 还的时间点  0 钥匙编号  1 借还时间  2 (0表示还)    # 优先按照借还时间点排序    # 如果借的时间点 == 还的时间点,优先让还排在前面    # 如果同一时间有多把钥匙还,则优先让编号小的排在前面    timeList = sorted(timeList, key=lambda item: (item[1], item[2], item[0]))    for item in timeList:        if item[2] == 1:  # 借            keyList[keyList.index(item[0])] = None        elif item[2] == 0:            keyList[keyList.index(None)] = item[0]    for item in keyList:        print(item, end=" ")index()

学生排队

def index():    stuSum = int(input())    changeSum = int(input())    stuList = [i + 1 for i in range(stuSum)]    changeList = []    for i in range(changeSum):        ls = [int(item) for item in input().split()]        changeList.append(ls)    for c in changeList:        index = stuList.index(c[0])        stuList.remove(c[0])        stuList.insert(index + c[1], c[0])    for stu in stuList:        print("%d" % stu, end=" ")index()

工资计算

def index():    n = int(input())    # 如果高于3500才开始判断  否则不需要交税    if n > 3500:        # 税前收税点        prevMoney = [0, 1500, 4500, 9000, 35000, 55000, 80000]        prevMoney = [item + 3500 for item in prevMoney]        # 对应的税率        prevS = [0.03, 0.1, 0.2, 0.25, 0.3, 0.35, 0.45]        # 税前收税点转化后的税后收税点        afterMoney = []        afterMoney.append(3500)        # 按照 税前工资 + 税率 计算出税后收税点        # 每一个税点: 前一个税后税点的钱 + (第i个税前税点的钱 - 第i-1税前税点的钱) * 税率        for i in range(1, len(prevMoney)):            afterMoney.append(int(afterMoney[i - 1] + (prevMoney[i] - prevMoney[i - 1]) * (1 - prevS[i - 1])))        # 初始化税后工资的段位为最后一个        position = len(prevMoney)        # 找到n在税后工资里的段位  如果没有找到 则说明 n 在税前 > 80000        for i in range(len(afterMoney)):            if n < afterMoney[i]:                position = i                break        # 因为最高税率也就 0.45 所以 最高的税前价格 不会超过税后价格的两倍,这里的两倍其实是大了的        # 所以可得 afterMoney[position-1] < n < 2 * n        # 将afterMoney[position-1]设为最小值        minMoney = prevMoney[position - 1]        # 将2 * n 设为最大值        maxMoney = 2 * n        # 因为题目说 税前工资是一个整百的数,所以可以每次遍历都+100        for money in range(minMoney, maxMoney, 100):            # 这里的money模拟的是税前工资 需要把money进行运算 再而判断是否与税后工资一致            # (1) = (money - minMoney) * (1 - prevS[position - 1])  在[position-1,position]区间需要交的税后工资            # (2) = afterMoney[position-1]  在[0,position-1]的税后工资            # 总税后工资 = [0,position-1] 的全部税后工资 + [position-1,position] 部分税后工资            # 总税后工资 =  afterMoney[position - 1] +  (money - minMoney) * (1 - prevS[position - 1])            if int((money - minMoney) * (1 - prevS[position - 1])) + afterMoney[position - 1] == n:                print(money)                break    # 没有超过3500的工资不用交税  直接输出原工资    else:        print(n)index()

火车购票

class Seat:    # 创建一排座位    def __init__(self, startNum):        self.seat = [i for i in range(startNum, startNum + 5)]    def isFull(self):        return len(self.seat) == 0    def getSeatNum(self):        return len(self.seat)    def buySeat(self, num):        if len(self.seat) < num:            return -1        else:            return [self.seat.pop(0) for i in range(num)]def index():    n = int(input())    buyList = list(map(int, input().split()))    if n > 20:        n = 20    car = []  # 车厢 车厢包括 20排座位    retList = []  # 存储每次购买的位置    for i in range(n):        s = Seat(i * 5 + 1)        car.append(s)    # 优先买相邻的座位,如果没有 则从第一节车厢遍历,有位置就买    for item in buyList:        for s in car:            if s.getSeatNum() >= item:                retList.append(s.buySeat(item))                break        # 如果找不到相邻的座位        else:            ls = []            for s in car:                buyNum = min(s.getSeatNum(), item)                ls += s.buySeat(buyNum)                item -= buyNum                if item == 0:                    break            retList.append(ls)    for i1 in retList:        for i2 in i1:            print(i2, end=" ")        print()index()

俄罗斯方块

def index():    # 俄罗斯方块盘    numList = []    # 即将添加的一块俄罗斯方块    addList = []    # 存储即将添加的俄罗斯方块的坐标    addZbList = []    for i in range(15):        ls = list(map(int, input().split()))        numList.append(ls)    for i in range(4):        ls = list(map(int, input().split()))        addList.append(ls)    # 俄罗斯方块将在期盼中的第column列出现    column = int(input())    # 在矩阵中 column-1 表示 第 column 列    column -= 1    # 获取即将添加的俄罗斯方块的坐标    for i in range(len(addList)):        for j in range(len(addList[i])):            if addList[i][j] == 1:                addZbList.append([i, j])    # 根据纵坐标排序  找出addZbList中最左边的方块    addZbList = sorted(addZbList, key=lambda item: item[1])    # 以排序后的 最左边的方块为起点 整体横向移动column 这样俄罗斯方块才能在期盼的第column列出现    addZbList = [[item[0], item[1] + column] for item in addZbList]    maxSize = -1    # 找到俄罗斯方块能下落到的最低点    for i in range(1, 15):        for item in addZbList:            # 如果没有到达底部 判断每个方块有没有触碰到 原来就存在的方块            if item[0] + i < 15:                if numList[item[0] + i][item[1]] == 1:                    maxSize = i - 1                    break            # 如果到达了底部            else:                maxSize = i - 1        # 如果找到了俄罗斯方块能下落到的最低点        if maxSize != -1:            break    # 把俄罗斯方块的坐标移到最低点    addZbList = [(item[0] + maxSize, item[1]) for item in addZbList]    for item in addZbList:        numList[item[0]][item[1]] = 1    for i1 in numList:        for i2 in i1:            print(i2, end=" ")        print()index()

消除类游戏

def index():    column, row = list(map(int, input().split()))    # 需要判断消除的矩阵    numList = []    for i in range(column):        ls = list(map(int, input().split()))        numList.append(ls)    # 用于存储坐标    numSet = set()    # 按行处理    for i, i1 in enumerate(numList):        for j in range(1, row - 1):            if i1[j - 1] == i1[j] == i1[j + 1]:                numSet.add((i, j - 1))                numSet.add((i, j))                numSet.add((i, j + 1))    # 按列处理    for i in range(row):        for j in range(1, column - 1):            if numList[j - 1][i] == numList[j][i] == numList[j + 1][i]:                numSet.add((j - 1, i))                numSet.add((j, i))                numSet.add((j + 1, i))    # 将numSet里的坐标在numList的对应位置消除(置为0)    for item in numSet:        numList[item[0]][item[1]] = 0    # 打印numList    for i1 in numList:        for i2 in i1:            print(i2, end=" ")        print()index()

日期计算

def isR(year):    if year % 4 == 0 and year % 100 != 0:        return True    elif year % 400 == 0:        return True    else:        return Falsedef getDay(day, r):    m = 1    d = getDayByMon(m, r)    while day > d:        day -= d        m += 1        d = getDayByMon(m, r)    return (m, day)def getDayByMon(d, r):    if d in [1, 3, 5, 7, 8, 10, 12]:        return 31    elif d in [4, 6, 9, 11]:        return 30    elif d == 2:        if r:            return 29        else:            return 28def index():    y = int(input())    d = int(input())    MD = getDay(d, isR(y))    print(MD[0])    print(MD[1])index()

数字排序

def index():    n = int(input())    numList = list(map(int, input().split()))    numDic = {}    for num in numList:        if num not in numDic:            numDic[num] = 1        else:            numDic[num] += 1    retList = sorted(numDic.items(), key=lambda item: (item[1], item[0]))    retList.sort(key=lambda item: item[1], reverse=True)    for item in retList:        print(item[0], item[1])index()

画图

def index():    n = int(input())    zbList = []    for i in range(n):        zbList.append(tuple(map(int, input().split())))    zbSet = set()    for item in zbList:        for i in range(item[0], item[2]):            for j in range(item[1], item[3]):                zbSet.add((i, j))    print(len(zbSet))index()

窗口

def index():    windowSize, touchSize = map(int, input().split())    windowList = []  # 窗口坐标列表    touchList = []  # 点击坐标列表    retList = []  # 最终结果列表    # 录入每个窗口坐标    for i in range(windowSize):        t1 = tuple(map(int, input().split()))        t2 = (i + 1,)        t = t1 + t2        windowList.append(t)    # 录入每个点击的点的坐标    for i in range(touchSize):        touchList.append(tuple(map(int, input().split())))    for i in range(touchSize):        windowNum = -1        window = None        for j in range(windowSize):            # (windowSize - 1 - j) 使得遍历的时候变成倒序遍历            # 如果鼠标点击的坐标在该窗口的范围内            if touchList[i][0] >= windowList[windowSize - 1 - j][0]:                if touchList[i][0] <= windowList[windowSize - 1 - j][2]:                    if touchList[i][1] >= windowList[windowSize - 1 - j][1]:                        if touchList[i][1] <= windowList[windowSize - 1 - j][3]:                            # 记录被点击到的window                            window = windowList[windowSize - 1 - j]                            break        # 如果遍历完windowNum还是-1 说明没有点击到窗口        if window == None:            retList.append("IGNORED")        else:            # 否则将窗口放到列表的最后  注意:这里是从最后开始遍历            if len(windowList) > 1:                windowList.remove(window)                windowList.append(window)            retList.append(window[4])    for item in retList:        print(item)index()

ISBN号码

def index():    string = input()    stringList = list(string.replace("-", ""))    # 获取到最后一个字符    lastNum = stringList[-1]    stringList = [int(item) for item in stringList[:len(stringList) - 1]]    s = 0    for i in range(len(stringList)):        s += stringList[i] * (i + 1)    mod = s % 11    if mod == 10:        if lastNum == "X":            print("Right")        else:            string = list(string)            string[-1] = "X"            string = ''.join(string)            print(string)    else:        if lastNum == str(mod):            print("Right")        else:            string = list(string)            string[-1] = str(mod)            string = ''.join(string)            print(string)index()

-END-

04

往期


Python版 CSP目前所有第一题

你可能感兴趣的:(ccf碰撞的小球python,think,in,python,第二版)