1-双十一的祈祷
2-疯狂的促销
3-被替换的身份证
t = int(input())
p = "3456789XJQKA2MF"
def lar(a):
return max(p.index(a[0]), p.index(a[1]))
for i in range(t):
s, j = input().split()
if s[0] == s[1] or s == "MF" or s == "FM":
print("ShallowDream")
else:
if j == "MF" or j == "FM":
print("Joker")
elif lar(s) >= lar(j):
print("ShallowDream")
else:
print("Joker")
4-迷宫逃脱
方法1:动态规划
from math import gcd # gcd(任何数, 0) = abs(任何数)
N, M, Q = map(int, input().split())
# 任意(i, j)均是从(i - 1, j)和(i, j - 1)转移
a = [[0] * (M + 1) for _ in range(N + 1)]
for i in range(1, N + 1):
temp = list(map(int, input().split()))
for j in range(1, M + 1):
a[i][j] = temp[j - 1]
# dp[i][j][k]走到(i, j)消耗 k 把钥匙的最大值
dp = [[[0] * (Q + 1) for _ in range(M + 1)] for _ in range(N + 1)]
dp[1][1][0] = a[1][1] # 完成初始化 i, j, k 均只与前一个相关
for i in range(1, N + 1): # 针对每一个位置
for j in range(1, M + 1):
""" 情况1:从a[i - 1][j]转移 """
if gcd(a[i][j], a[i - 1][j]) != 1: # 无需钥匙
for k in range(Q + 1): # 更新每一个维度
if dp[i - 1][j][k] != 0: # 否则不能从(i - 1,j)转移
dp[i][j][k] = dp[i - 1][j][k] + a[i][j]
else: # 需要钥匙 Q 从 1 开始 dp[i][j][0] = 0
for k in range(1, Q + 1): # 更新每一个维度
if dp[i - 1][j][k - 1] != 0: # 否则不能从(i - 1,j)转移
dp[i][j][k] = dp[i - 1][j][k - 1] + a[i][j]
""" 情况2:从a[i][j - 1]转移 需要与第一种情况做比较"""
if gcd(a[i][j], a[i][j - 1]) != 1: # 无需钥匙
for k in range(Q + 1): # 更新每一个维度
if dp[i][j - 1][k] != 0: # 否则不能从(i,j - 1)转移
dp[i][j][k] = max(dp[i][j][k], dp[i][j - 1][k] + a[i][j])
else: # 需要钥匙Q从1开始 dp[i][j][k] = 0
for k in range(1, Q + 1): # 更新每一个维度
if dp[i][j - 1][k - 1] != 0: # 否则不能从(i,j - 1)转移
dp[i][j][k] = max(dp[i][j][k], dp[i][j - 1][k - 1] + a[i][j])
ans = 0
for i in range(Q + 1): # 寻找到达(N, M)缩小后钥匙不超过 Q 把的最大值
ans = max(ans, dp[N][M][i])
print(ans if ans != 0 else -1)
方法2:记忆化搜索
import sys
from math import gcd
sys.setrecursionlimit(1000010)
def dfs(i, j, k): # 和动态规划的类似
if k == -1: # 出口1:保证 dp[i][j][k] 不大于 0 即不可达
return -sys.maxsize
if i == N and j == M: # 出口2:达到最低端 类似于初始化dp[1][1][0] = a[1][1]
return a[N][M]
if dp[i][j][k] != -sys.maxsize: # 记忆化
return dp[i][j][k]
"""情况1:往左走(i, j + 1)"""
if j + 1 <= M: # 没有越界
if gcd(a[i][j], a[i][j + 1]) == 1: # 需要钥匙
dp[i][j][k] = max(dp[i][j][k], dfs(i, j + 1, k - 1) + a[i][j])
else: # 不要钥匙
dp[i][j][k] = max(dp[i][j][k], dfs(i, j + 1, k) + a[i][j])
"""情况2:往下走(i + 1, j)"""
if i + 1 <= N:
if gcd(a[i][j], a[i + 1][j]) == 1: # 需要钥匙
dp[i][j][k] = max(dp[i][j][k], dfs(i + 1, j, k-1) + a[i][j])
else: # 不要钥匙
dp[i][j][k] = max(dp[i][j][k], dfs(i + 1, j, k) + a[i][j])
return dp[i][j][k]
"""读入数据"""
N, M, Q = map(int, input().split())
a = [[0] * (M + 1) for _ in range(N + 1)]
for i in range(1, N + 1):
temp = list(map(int, input().split()))
for j in range(1, M + 1):
a[i][j] = temp[j - 1]
# 初始化为 -inf 表示不可到达
dp = [[[-sys.maxsize] * (Q + 1) for _ in range(M + 1)] for _ in range(N + 1)]
ans = dfs(1, 1, Q)
print(ans if ans > 0 else -1)
5-深秋的苹果
def check(arr, Sum, length, count, num):
ind = 1; val = 0; cnt = 1
for i in range(1, length + 1):
val += arr[i] * (Sum[i - 1] - Sum[ind - 1])
if val >= num: # 重新开始一段
val = 0; ind = i; cnt += 1
return cnt <= count # 在 num 的条件下 所得段数小于等于要求 说明 num 小或等于
N, M = map(int, input().split())
lst = [0] + list(map(int, input().split()))
S = [0] * (N + 1) # 前缀和
for i in range(1, N + 1):
S[i] = S[i - 1] + lst[i]
left = 0; right = 2 * 10 ** 18
while left <= right:
mid = (left + right) >> 1
if(check(lst, S, N, M, mid)): # mid小或等于
right = mid - 1
else:
left = mid + 1
print(right)
6-鲜花之海
def calc(N, K): # 计算下三角形 K 所在横纵坐标
left = 1; right = N
while left <= right:
mid = (left + right) >> 1
if mid * (mid + 1) >= 2 * K:
right = mid - 1
else:
left = mid + 1
K -= right * (right + 1) // 2
return K, left - K + 1
for _ in range(int(input())):
N, K = map(int, input().split())
if 2 * K <= N * (N + 1): # 当前数字在三角形下面
x, y = calc(N, K)
else: # 当前数字在三角形上方
K = N * N - K + 1
x, y = calc(N, K)
x = N - x + 1; y = N - y + 1
print(x, y)