1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
| import os import sys
from datetime import datetime, timedelta
def last_bell_time(): """ 某个设备每隔 x 分钟响一次铃,问在给定时间前最后一次响铃的具体时间。
【输入说明】 - 第一行输入一个整数 T,表示有 T 组测试数据 - 每组测试数据输入一行:一个时间字符串 + 一个整数 x(分钟)
【输出说明】 - 每组输出最近一次响铃的时间,格式为 yyyy-MM-dd HH:MM:SS
【样例输入】 2 1973-12-06 00:08:38 5 2001-01-01 00:00:01 1
【样例输出】 1973-12-06 00:05:00 2001-01-01 00:00:00
【解题思路】 - 目标是找到当前时间之前最近一次响铃的时间。 - 可以将时间统一转化为“从1970-01-01 00:00:00开始的总秒数” - 时间间隔为 x 分钟,即 x × 60 秒 - 使用整除运算 `(totalsec // interval) * interval` 找到最近一次响铃的秒数 - 然后将这个秒数再转回时间格式并输出
【重点函数】 - datetime.strptime(str, fmt):将字符串转换为 datetime 对象 - datetime.strftime(fmt):将 datetime 对象格式化为字符串 - timedelta(seconds=n):创建一个时间差(可加减时间) - total_seconds():计算两个时间对象之间的差值,返回秒数
【完整代码】 """
T = int(input()) for _ in range(T): line = input() strtime, x = line.rsplit(" ", 1)
start = datetime(1970, 1, 1, 0, 0, 0) objtime = datetime.strptime(strtime, "%Y-%m-%d %H:%M:%S") totalsec = int((objtime - start).total_seconds())
interval = int(x) * 60 lasttimesec = (totalsec // interval) * interval
lasttime = start + timedelta(seconds=lasttimesec) print(lasttime.strftime("%Y-%m-%d %H:%M:%S"))
def count_diagonal_pairs(): """ 小蓝正在和朋友们玩一种新的连连看游戏。
在一个 n × m 的矩形网格中,每个格子中都有一个整数,第 i 行第 j 列上的整数为 A[i][j]。 玩家需要寻找一对格子 (a,b)-(c,d),使得: 1. A[a][b] == A[c][d] 2. |a - c| == |b - d| > 0
问有多少对格子满足以上条件。
--------------------------------------- ✅ 条件转化为: 满足 |a - c| == |b - d| 的点,表示它们在 ↘ 或 ↙ 方向上的对角线上。 所以我们按如下方式判断是否在同一对角线上: - ↘ 方向:i - j 相同(从左上到右下) - ↙ 方向:i + j 相同(从右上到左下)
--------------------------------------- 解题思路: - 用两个字典 diag1, diag2,分别记录 ↘ 和 ↙ 对角线上每个数字 val 出现的次数。 - 遍历每个格子,如果当前数值 val 在该对角线上已出现 k 次,就可以与前面 k 个 val 组成 k 个合法格子对。 - 每次发现就累计 k,之后把 val 的出现次数 +1。
数据结构: diag1[i - j][val] -> 统计↘方向上该值出现次数 diag2[i + j][val] -> 统计↙方向上该值出现次数
注意:只能使用 os 和 sys 标准库,所以不用 collections.defaultdict """
import sys input = sys.stdin.readline
n, m = map(int, input().split()) grid = [list(map(int, input().split())) for _ in range(n)]
diag1 = {} diag2 = {} ans = 0
for i in range(n): for j in range(m): val = grid[i][j]
key1 = i - j if key1 not in diag1: diag1[key1] = {} if val in diag1[key1]: ans += diag1[key1][val] diag1[key1][val] += 1 else: diag1[key1][val] = 1
key2 = i + j if key2 not in diag2: diag2[key2] = {} if val in diag2[key2]: ans += diag2[key2][val] diag2[key2][val] += 1 else: diag2[key2][val] = 1
print(ans * 2)
def count_valid_strings(): """ 小蓝要构造一个长度为 10000 的数字字符串,有以下要求:
1. 不能出现数字 0; 2. 必须包含数字 3 和数字 7。
求满足要求的字符串个数,结果对 10^9 + 7 取模。
解题思路: - 所有可能的字符串总数为 9^10000(每位可选1~9) - 使用容斥原理排除不合法情况: - 不含3的有 8^10000 种 - 不含7的有 8^10000 种 - 同时不含3和7的有 7^10000 种 - 合法数量 = 9^10000 - 2 * 8^10000 + 7^10000 - 使用快速幂计算大指数,最后对 10^9 + 7 取模 """ MOD = 10 ** 9 + 7
total = pow(9, 10000, MOD) no_3 = pow(8, 10000, MOD) no_7 = pow(8, 10000, MOD) no_3_and_7 = pow(7, 10000, MOD)
result = (total - 2 * no_3 + no_3_and_7) % MOD
print(result)
def max_coin_count(): """ 小蓝手中有 2023 种不同面值的新版硬币, 第 i 种硬币面值为 i,数量也为 i。 可以使用两个新版硬币兑换一个面值为 coin1 + coin2 的旧版硬币。 问:通过任意兑换后,某个面值的硬币最多能有多少个? """ result = [0 for _ in range(4047)]
for i in range(1, 2024): for j in range(i + 1, 2024): result[i + j] += i
print(max(result))
""" 12345678 到 98765432 有多少个数完全不包含2023 def findIt(i): find01 = i.find('2') if find01 == -1: return 0
find02 = i.find('0', find01+1) if find02 == -1: return 0
find03 = i.find('2', find02+1) if find03 == -1: return 0
find04 = i.find('3', find03+1) if find04 == -1: return 0
return 1
count = 0 for i in range(12345678, 98765432 + 1): if findIt(str(i)) == 0: count += 1 print(count) """
def rotate(self, nums, k: int) -> None: """ 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 """ def reverse(left: int, right: int): while left < right: nums[left], nums[right] = nums[right], nums[left] left += 1 right -= 1 n = len(nums) k %= n reverse(0, n-1) reverse(0, k-1) reverse(k, n-1)
def plusOne(self, digits):
for i in range(len(digits) - 1, -1, -1): if digits[i] < 9: digits[i] += 1 return digits digits[i] = 0 return [1] + [0] * len(digits)
def pivotIndex(self, nums) -> int: """ 给你一个整数数组 nums ,请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。 如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。 """ suml, sumr = 0, sum(nums) for i in range(len(nums)): sumr -= nums[i] if sumr == suml: return i suml += nums[i] return -1
def prefixSuffix(nums): """ 给你一个整数数组 nums,返回一个新的数组 answer,其中 answer[i] 等于 nums 中 左侧所有元素的和 与 右侧所有元素的和 之和。 要求:不要使用额外的数组(即 O(1) 额外空间,除了 answer 本身)。时间复杂度为 O(n)。 """ n = len(nums) pre = [0] * n suf = [0] * n for i in range(1, n): pre[i] = pre[i - 1] + nums[i - 1] for i in range(n - 2, -1, -1): suf[i] = suf[i + 1] + nums[i + 1] return [p + s for p, s in zip(pre, suf)]
|