目录
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])