赞
踩
第三年蓝球杯,感觉题目比往年简单多了。题量合适够我这种菜鸟解答... ...
大概可能有45分,希望进省一大三最后i一次机会了55555
进省一了耶耶耶
多此一举的输出纯粹怕粗心。
- def check(a):
- jin_2, x2 = jin_s(a, 2)
- jin_4, x4 = jin_s(a, 4)
- print(a, x2, x4)
- if jin_2 == jin_4:
- return True
- return False
-
-
- def jin_s(x, m):
- res = []
- while x:
- res.append(x%m)
- x //= m
- return sum(res), res
-
-
- def main():
- res = 0
- for i in range(1, 2025):
- if check(i):
- res += 1
- print(res, '**************')
- # 63
- if __name__ == '__main__':
- main()
- def main():
- n = 10000
- p = int(1e9 +7)
- dp = [[[0] * 2 for i in range(2)] for j in range(n+1)]
-
- # 前缀指的是不包括当前字符串的前子串
- # 状态为[当前str长度][前缀是否有3][前缀是否有7]
-
- # 边界
- dp[1][0][0] = 7 # 没有3和7,只能是除37的其它七种方案
- dp[1][0][1] = 1 # 有3,一种方案
- dp[1][1][0] = 1 # 有7,一种方案
- dp[1][1][1] = 0 # 有3和7,不可能(长度为1不可能同时出现37)
-
- # 枚举阶段,决策为当前i位置填什么字符
- for i in range(2, n+1):
- # 状态转移
- dp[i][0][0] = (dp[i-1][0][0] * 7) % p # 前缀无37(当前可填7种1、2、4、5、6、8、9)
- dp[i][0][1] = (dp[i-1][0][1] * 8 + dp[i-1][0][0]) % p # 从有7(可填8种)、和均没有(可填1种)
- dp[i][1][0] = (dp[i-1][1][0] * 8 + dp[i-1][0][0]) % p # 从有3(可填8种)、和均没有(可填1种)
- dp[i][1][1] = (dp[i-1][1][1] * 9 + dp[i-1][0][1] + dp[i-1][1][0]) % p # 从有37(可填9种)、只有3(1种)、只有7(1种)三种情况
-
- # 答案
- print(dp[n][1][1]) # 157509472
-
-
- if __name__ == '__main__':
- main()
- import sys
- def main():
- input = lambda: sys.stdin.readline().strip() # 快读
- n, m = map(int, input().split())
- maps = []
- hax0 = [[0]*1001 for i in range(2001)] # 斜行=> '\'
- hax1 = [[0]*1001 for i in range(2001)] # 斜行=> '/'
- for i in range(n):
- maps.append(list(map(int, input().split())))
-
- # 记录这一斜行每个元素出现次数
- for j, x in enumerate(maps[-1]):
- hax0[(i-j) % 2000][x] += 1
- hax1[(i+j) % 2000][x] += 1
- res = 0
- for i in range(n):
- for j in range(m):
- ai = maps[i][j]
-
- # 因为要排除自己,所以需要大于1才行,还需要-1。
- # 例如当前斜行有2个相等元素,有一个是自己,所以只能配成一对
- if hax0[(i-j) % 2000][ai] > 1:
- res += hax0[(i-j) % 2000][ai] - 1
- if hax1[(i+j) % 2000][ai] > 1:
- res += hax1[(i+j) % 2000][ai] - 1
- print(res)
-
-
- if __name__ == '__main__':
- main()
- import sys
- from datetime import datetime, timedelta # 时间类、时间差值类
- def main():
- input = lambda: sys.stdin.readline().strip()
- start = datetime(1970, 1, 1, 0, 0, 0)
- for i in range(int(input())):
- aa, bb, mmm = input().split()
-
- n, y, r = map(int, aa.split('-'))
- s, f, m = map(int, bb.split(':'))
-
- # 和秒没有关系,因为从0:0:0开始,又是整数间隔分钟
- # 实例化当前时间
- now = datetime(n, y, r, s, f, 0)
-
- # 到目前的差值时间
- diff = now - start
-
- # 计算差值时间的 (mod 间隔)的余数
- totmins = int(diff.total_seconds())//60%int(mmm)
-
- # 把当前时间前移 差值对间隔余多少分钟
- print(str(now-timedelta(minutes=totmins)))
-
- if __name__ == '__main__':
- main()
然后发现,n是3的倍数答案就是n*2,不是3的倍数答案就是n本身
- import sys
-
-
- def check(n, xxxxx):
- """
- 检查该排列是否符合要求
- :param n:
- :param xxxxx: 用来拆分的数
- :return:
- """
- # 拆分二进制,枚举集合状态
- lis = []
- while xxxxx:
- lis.append(xxxxx%2)
- xxxxx //= 2
-
- res = [0] *(n-len(lis)) + lis # 不够长的补0
-
- # 扩大一倍,解决环的问题
- lis = res * 2
- for i in range(n):
- if lis[i] == 1:
- if lis[i+1] ^ lis[i+2] == 0:
- return False, res
- else:
- if lis[i+1] ^ lis[i+2] == 1:
- return False, res
- return True, res
-
- def sol(n):
- """
- 这是用来暴力找规律的
- """
- ans = 0
- for i in range((2**n)):
- flag, lis = check(n, i)
- if flag:
- print(lis)
- ans += lis.count(0)
- print(n%3, n, ans, "***************"*5)
-
- def main():
- input = lambda: sys.stdin.readline().strip()
- t = int(input())
-
- # 用来暴力的
- # for n in range(3, 22):
- # sol(n)
-
- for i in range(t):
- n = int(input())
- if n%3 == 0:
- print(n*2)
- else:
- print(n)
-
- if __name__ == '__main__':
- main()
赛后补题 例如:
126 393 581 42 44
204 990 240 46 52
贪心的话直接选择第一个满足的就行了,所以难点就是快速找满足条件的第一个
两组满足条件的下标入数组
1 4 5
1 2 3 4 5
直接二分查找,交替找第一个大于上一块石头下标就行了... ...
真简单,大无语事件因为字多不想看... ...
- import re
- import bisect
-
-
- def solution(A, B):
- if not A: # 小蓝一个都拿不了
- return 0
- left = A[0] # 小蓝开始贪心拿第一个
- cnt = 1 # 答案
- cur_lis = B # 交替的数组,小蓝选了一个,接下来小乔选
- while True:
- try:
- left = cur_lis[bisect.bisect(cur_lis, left)] # 不断用二分交替找第一个大于的数
- cnt += 1
- cur_lis = A if cur_lis is B else B
- except: # 直接用异常来判断结束
- return cnt
-
-
- if __name__ == '__main__':
- n = int(input())
-
- # 使用re筛选含有024的符文数字
- pat = re.compile('[024]')
-
- # 把符合调节的符文下标存入待选数组
- # A 为小蓝待选, B为小乔
- A = [i for i, x in enumerate(input().split(), 1) if pat.search(x)]
- B = [i for i, x in enumerate(input().split(), 1) if pat.search(x)]
- print(solution(A, B))
-
-
所以直接kruskal,然后并查集维护连通块大小,从大到小遍历,(并查集维护不小于某边权的最大连通)。
如果通过一条边能连接两个连通块,说明这条边是两个连通块,全连接(相互到达)的最大边权,也就是最贵的一条路。所以连接前的两个连通块,都能组成一对符合条件的点对故size[u]*size[v]。
就是忘记了并查集如何维护size,忘记了合并的时候这个 size += size该写在哪里... ...
痛失20分,我还调试了一个半小时。
以下代码只能得到91%分,原因不详
- import sys
-
- def main():
- input = lambda: sys.stdin.readline().strip()
- def find(x):
- nonlocal fa, size
- if x != fa[x]:
- fa[x] = find(fa[x])
- return fa[x]
-
- def merge(x, y):
- nonlocal fa, size
- xx, yy = find(x), find(y)
- if xx == yy:
- return False
- fa[xx] = yy
- size[yy] += size[xx]
- return True
-
-
- n, m, LL, RR = map(int, input().split())
- size = {i: 1 for i in range(1, n + 1)}
- fa = {i: i for i in range(1, n + 1)}
- edges = []
- for i in range(m):
- u, v, w = map(int, input().split())
-
- # 不满足的边直接筛掉
- if w > RR or w < LL:
- continue
- edges.append((w, u, v))
- ans = 0
-
- # 并查集维护不小于某边权的集合
-
- # 从大到小枚举,并且去除不符合条件的边
- for w, u, v in sorted(edges, reverse=True):
- aa, bb = find(u), find(v)
-
- # 记录连通前两个连通块的全连接大小
- temp = size[aa] * size[bb]
-
- # 如果是第一次连接两个集合,说明该边是两个连通块的最大连接边(最贵的路)
- if merge(u, v):
- ans += temp
- print(ans)
-
-
- if __name__ == '__main__':
- main()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。