寒假备赛蓝桥杯Python组训练题二

目录

1.穿越雷区

2.小朋友崇拜圈

3.调手表 

4.包子凑数

5.日志统计

6.金币

7.神奇的幻方

1.穿越雷区

解题思路:bfs搜索 (队列或列表)

import os
import sys

n=int(input())
mp=[list(map(str,input().split()))for i in range(n)]
vis=[[0]*n for i in range(n)]
dir=[(0,1),(0,-1),(1,0),(-1,0)]
q=[]
ex,ey=0,0
for i in range(n):
    for j in range(n):
        if mp[i][j]=='A':
            q.append((i,j,'',0))
            vis[i][j]=1
        if mp[i][j]=='B':
            ex,ey=i,j

##  (x,y,pre,step)  # 当前坐标,上上一步状态,步数
def bfs():
    global ex,ey
    while q:
        x,y,s,step=q.pop(0)
        for i,j in dir:
            nx,ny=x+i,y+j
            if nx<0 or nx>=n or ny<0 or ny>=n:
                continue
            if vis[nx][ny]==1 or mp[nx][ny]==s:
                continue
            vis[nx][ny]=1
            if nx==ex and ny==ey:
              return step+1
            q.append((nx,ny,mp[nx][ny],step+1))


print(bfs())

2.小朋友崇拜圈

import os
import sys


sys.setrecursionlimit(1000000)
n=int(input())
f=[0]+list(map(int,input().split()))
vis=[0]*(n+1)
global ans
ans=0

def dfs(u,i):
    if vis[u]:#vis[u]访问过
        global ans
        ans=max(ans,i-vis[u])#用当前列表长度i减去已经在T中的那个小朋友的下标
        return
    vis[u]=i
    dfs(f[u],i+1)#f[u]:寻找下一个崇拜者  i+1:当前构成环的长度+1

for i in range(1,n+1):
    if not vis[i]:
      dfs(i,1)#从i开始遍历,环默认为1
print(ans)

3.调手表 

import os
import sys

N,K=map(int,input().split())

# 初始化状态1,记录按+1键得到要调i分钟需要的次数
dp=[i for i in range(N)] 

# 初始化状态2, 记录按i次K键得到各分钟需要次数的最小值,
for i in range(N):

    val = i * K % N  # 每次得到K的倍数,若大于N则取余

    dp[val] = min(i,dp[val])  # 该位置取全按K键和全按+1键的最小值
    
for i in range(1,N):  # 寻找最优子结构
    # 要么是通过上个数按+1键得到
    #要么按+K键得到,而这样得到算按一次所以要+1
    # 要么是本身,如果是本身说明该分钟是K的倍数,在初始化时已达最优
    # 取三者最小值
    dp[i]=min(dp[i-1]+1,dp[i-K]+1,dp[i])
  
print(max(dp))

4.包子凑数

import os
import sys

# 请在此输入您的代码
import math
N = 10000
dp = [0 for i in range(N)]
n = int(input())  # n 为第几个笼子
a = [int(input()) for j in range(n)]  # 循环输入每个笼子中的小笼包数量
g = a[0]
for i in range(n):
    g = math.gcd(g,a[i])  
    # 求得笼子中的小笼包数量的最大公约数,
    # 若不为1,则说明其任意组合可以表示,固有无限可能,需要输出INF
if g == 1:  #  使用完全背包算法求解不能表示的数
    dp[0] = 1  # 将第一个数标记为1
    for i in range(n):  # 有几种笼子的类型就遍历几种
        for j in range(a[i],N):  # a[i]对应的是笼子中的小笼包数量
            dp[j] = max(dp[j],dp[j-a[i]])  # 状态转移方程式,
            # j-a[i]相当于反向从10000开始递减单个笼子的数量,从而达到单个倍数的可能性,并给可以取到的数标记为1
            # 对于组合数,比如3,4,5、7咱们又是如何取得到的呢?
            #  dp[7]=0,但是dp[7-a[i]]=dp[7-4]=dp[3]=1,
            # 也就是说这个数可以被第一个数和第二个数相加得到,因此也可以被标记
    print(N-sum(dp))
else:
    print('INF')

5.日志统计

import os
import sys

'''
题意:
    ①输入三个数:日志个数N,时间间隔D,赞K
    ②统计热帖
思路:字典
    1、处理数据:将N行数据处理成字典类型:id:出现时刻
    2、统计每一个id下,在d~d+D的时间段上,收到的赞个数
    3、超过K个,则存入列表ans
例子:
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
'''
def check(D,K,ts_):
  for x in ts_:
    count = 0
    for y in ts_:
      if x <= y < x+D:
        count += 1
      if count >= K:
        return True
  return False

N, D, K = map(int,input().split())
d = dict()
#将N行数据存储为字典模式:里面数据id:时刻
# {1: [0, 10, 9], 10: [0, 10], 3: [100, 100]}
for _ in range(N):
  ts,ids = map(int,input().split())
  d[ids] = d.get(ids,[]) +[ts]
# print(d)

ans = [] #存储热帖id 
# dict_items([(1, [0, 10, 9]), (10, [0, 10]), (3, [100, 100])])
for j in d.items():
  ids, ts_ = (i for i in j)
  ts_ = sorted(ts_)
  if check(D,K,ts_):
    ans.append(ids)

for i in sorted(ans):
  print(i)

6.金币

import os
import sys

# 请在此输入您的代码
k=int(input())
i=1
N=0
while k>=i:
    k-=i
    N+=i*i
    i+=1
if k!=0:
    N+=k*i
print(N)

7.神奇的幻方

import os
import sys

n=int(input())
hf=[[0]*n for i in range(n)]
hf[0][n//2]=1
x,y=0,n//2
for i in range(2,n**2+1):
  if x==0 and y!=n-1:
    x,y=n-1,y+1
    hf[x][y]=i
  elif x!=0 and y==n-1:
    x,y=x-1,0
    hf[x][y]=i
  elif x==0 and y==n-1:
    x,y=x+1,y
    hf[x][y]=i
  else:
    if hf[x-1][y+1]==0:
      x,y=x-1,y+1
      hf[x][y]=i
    else:
      x,y=x+1,y
      hf[x][y]=i
for l in range(n):
  print(*hf[l])

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值