'''
這一題我的解法 1 : NA (score:91%)
因為測資 #11 的 n 值比較大,第一個寫法
使用了比較大的記憶體,解法 2 才 AC
請看說明。
'''
# 解法 1
from sys import *
n, m, q = map(int, stdin.readline().split())
N = {k: [k-1, k+1] for k in range(n)}
# 建立一個 dict ,且預設每個 key 的逆鄰及順鄰。
# n 值太大時,記憶體會不夠用,題目只有開 64MB
N[0][0] = n-1 # 頭尾手牽手
N[n-1][1] = 0
for _ in range(m):
d, a, b = stdin.readline().split()
a, b = int(a), int(b)
if(a == b): continue # a, b 相等時,不處理。
afk = N[a][1] # 因為 a 要抽走,先找出 a 的順鄰 afk 及逆鄰 ark
ark = N[a][0]
N[afk][0] = ark # 讓 afk 和 ark 手牽手,修補這個缺口。
N[ark][1] = afk
if(d == 'F'): # 如果指令是 F a 要放在 b 的順鄰。
bfk = N[b][1] # 先找出 b 原本的順鄰 bfk
N[bfk][0] = a # 設定 bfk 的逆鄰為 a
N[a][1] = bfk # 設定 a 的順鄰為 bfk
N[a][0] = b # 設定 a 的逆鄰為 b
N[b][1] = a # 設定 b 的順鄰為 a
else: # 如果指令是 R a 要放在 b 的逆鄰。
brk = N[b][0] # 先找出 b 原本的逆鄰 brk
N[brk][1] = a # 設定 bfk 的順鄰為 a
N[a][0] = brk # 設定 a 的逆鄰為 brk
N[a][1] = b # 設定 a 的順鄰為 b
N[b][0] = a # 設定 b 的逆鄰為 a
Q = [N[int(x)] for x in stdin.readline().split()]
r = ' '.join(['{} {}'.format(a, b) for a, b in Q])
print(r)
# 解法 2
from sys import *
n, m, q = map(int, stdin.readline().split())
N = {}
# 建立一個空的 dict ,不給初值,有用到的 key 才給值。
# 因為 m < 10^3 ,須建立的 key 不多,相信不會爆。
N[0] = [n-1,1] # 先建立頭尾的 key,一樣是頭尾手牽手
N[n-1] = [n-2, 0]
def initX(x): # 如果這個 key 值沒有出現過,它的 value 肯定是 [[x-1, x+1]]
global N
if(not N.__contains__(x)):
N[x] = [x-1, x+1]
return
def gp(x): # 這是要輸出的 string ,原理同 initX
global N
if(not N.__contains__(x)):
return '{} {}'.format(x-1, x+1)
else:
return '{} {}'.format(*N[x])
for _ in range(m):
d, a, b = stdin.readline().split()
a, b = int(a), int(b)
if(a == b): continue # a, b 相等時,不處理。
initX(a) # 對沒出現過的 key 給初值,底下同。
initX(b) #
afk = N[a][1]
ark = N[a][0]
initX(afk) #
initX(ark) #
N[afk][0] = ark
N[ark][1] = afk
if(d == 'F'):
bfk = N[b][1]
initX(bfk) #
N[bfk][0] = a
N[a][1] = bfk
N[a][0] = b
N[b][1] = a
else:
brk = N[b][0]
initX(brk) #
N[brk][1] = a
N[a][0] = brk
N[a][1] = b
N[b][0] = a
Q = [gp(int(x)) for x in stdin.readline().split()]
r = ' '.join(Q)
print(r)
2020/08/27
[zerojudge] f164: 萬球同心移位之章
2020/06/24
[zerojudge] e287: 機器人的路徑
import sys
n, m = [int(x) for x in sys.stdin.readline().split()]
f = []
for _ in range(n): f += [int(x) for x in sys.stdin.readline().split()]
v = f.index(min(f))
y, x, r = v // m, v % m, 0
while(1):
ind = y * m + x
r += f[ind]
f[ind] = -1
c = [[y, x+1], [y+1, x], [y, x-1], [y-1, x]]
c = [z for z in c if z[0] >= 0 and z[0] < n and z[1] >= 0 and z[1] < m]
if(not c): break
c = [(z[0], z[1], f[z[0] * m + z[1]]) for z in c]
c = [z for z in c if z[2] >= 0]
if(not c): break
c.sort(key = lambda z: z[2])
y, x, _ = c[0]
print(r)
2020/06/13
[zerojudge] e990: 奇怪的隕石
from sys import *
from math import log
for s in stdin:
t, n = map(float, s.split())
r = (log(n)/log(0.5))*t
print('%.3f' % r)
[zerojudge] a225 明明愛排列
import sys
for s in sys.stdin: print(' '.join(sorted(sys.stdin.readline().strip().split(), key = lambda x: (int(x)%10, -int(x)))))
2020/05/11
[zerojudge] f012: 奶油機器人
# 蘭頓螞蟻 Langton's ant python asnewchien@gmail.com
from sys import *
dot = {(0,0): 0} # 某點的顏色 0:white, 1:black
x, y = 0, 0 # position
direction = 0 # 方向 0:up, 1:right, 2:down, 3:left
r = [(0,0)] # 某一步的座標
rule = ({(0,0):(1,0,1,1), (0,1):(0,-1,2,1),(0,2):(-1,0,3,1),(0,3):(0,1,0,1),
(1,0):(-1,0,3,0),(1,1):(0,1,0,0), (1,2):(1,0,1,0), (1,3):(0,-1,2,0)})
# key of rule : (color, direction)
# value of rule : (deltaX, deltaY, newDirection, newColor)
for i in range(1, 10104):
op = (x, y) # 原來的點座標
oc = dot[op] # 原來的點顏色
dx, dy, direction, nc = rule[(oc,direction)]
dot[(x,y)] = nc # 給原來的點一個新顏色
x += dx
y += dy
if(not dot.__contains__((x,y))): dot[(x,y)] = 0
# 下一個點如果沒有拜訪過,設定為白色
r.append((x,y))
'''
我們現在要以 r[10000] 為基準點, 循環節為 104
我先做了一個測試,
發現 r[10000]=(-16, 10), r[10104]=(-18, 8), r[10208]=(-20, 6)
每個循環的起點對應上一個起點的 deltaX = -2, deltaY = -2
以下我要對 r[10000] ~ r[10103] 建立對 r[10000] 的相對位置
'''
# md = [(0, 0), (-1, 0), (-1, -1), (-2, -1), (-2, -2), (-3, -2), (-3, -1), (-2, -1), (-2, -2), (-1, -2), (-1, -3), (0, -3), (0, -2), (-1, -2), (-1, -3), (-2, -3), (-2, -2), (-1, -2), (-1, -3), (0, -3), (0, -4), (-1, -4), (-1, -5), (-2, -5), (-2, -4), (-1, -4), (-1, -5), (0, -5), (0, -4), (-1, -4), (-1, -5), (-2, -5), (-2, -6), (-3, -6), (-3, -5), (-2, -5), (-2, -6), (-1, -6), (-1, -7), (-2, -7), (-2, -6), (-1, -6), (-1, -5), (-2, -5), (-2, -6), (-1, -6), (-1, -7), (0, -7), (0, -8), (-1, -8), (-1, -7), (0, -7), (0, -6), (1, -6), (1, -5), (0, -5), (0, -4), (1, -4), (1, -3), (0, -3), (0, -4), (1, -4), (1, -5), (0, -5), (0, -6), (1, -6), (1, -7), (0, -7), (0, -6), (1, -6), (1, -5), (0, -5), (0, -4), (1, -4), (1, -3), (2, -3), (2, -2), (1, -2), (1, -1), (0, -1), (0, -2), (-1, -2), (-1, -3), (-2, -3), (-2, -4), (-1, -4), (-1, -5), (-2, -5), (-2, -4), (-1, -4), (-1, -3), (-2, -3), (-2, -2), (-3, -2), (-3, -3), (-4, -3), (-4, -2), (-3, -2), (-3, -3), (-2, -3), (-2, -2), (-1, -2), (-1, -3), (-2, -3), (-2, -2)]
md = []
baseX, baseY = r[10000]
for i in range(104):
x, y = r[10000+i]
md.append((x-baseX, y-baseY))
for s in stdin:
n = int(s)
try:
# n <= 10000
print('({},{})'.format(*r[n]))
except:
# n > 10000
v, u = divmod(n-10000, 104)
tx, ty = baseX+(-2)*v, baseY+(-2)*v
tx += md[u][0]
ty += md[u][1]
print('({},{})'.format(tx,ty))
2020/05/02
[zerojudge] e998: S形矩陣
from sys import *
A = list(map(str, range(1, 10001)))
# 一次建好型態為 string 的表
opt = '' # 最後一次印
for s in stdin:
n = int(s)
for i in range(n):
if(i%2==0): opt += ' '.join(A[i*n:i*n+n]) + ' \n'
else: opt += ' '.join(A[i*n:i*n+n][::-1]) + ' \n'
# i 為奇數時取出值,先反轉再 join
# i 為偶數時,直接 join
opt += '\n'
stdout.write(opt)
2020/04/20
[zerojudge] a450: 棒棒糖比身高
from sys import stdin
import bisect
# 請參考 https://docs.python.org/3/library/bisect.html
n, q = map(int, stdin.readline().split())
f = sorted([int(x) for x in stdin.readline().split()])
# 先排序
# 例如 8 5 10 11 8 會排序成 5 8 8 10 11
# 考慮到會有重複的元素
# 使用 bisect.bisect_left 取左邊位置
# bisect.bisect_right 取右邊位置
for _ in range(q):
a, b = map(int, stdin.readline().split())
a = bisect.bisect_left(f, a)
b = bisect.bisect_right(f, b)
r = b - a
if(r): print(r)
else: print('The candies are too short')
2020/04/13
[zerojudge] a121: 質數又來囉
from sys import stdin
def isPrime(n):
'''
參考 http://www.csie.ntnu.edu.tw/~u91029/Prime.html
質數判定
'''
if(n == 1): return 0
# 傳進來的 n 都已經過濾過,底下這 3 行先 mark 起來
#if(n in (2, 3)): return 1
#if(n % 2 == 0): return 0
#if(n%6 not in [1,5]): return 0
u = n - 1
t = 0
while(u % 2 == 0):
u >>= 1
t += 1
sprp = [2, 7, 61]
for sk in sprp:
a = sk % n
if (a == 0 or a == 1 or a == n-1): continue
x = pow(a, u, n)
if (x == 1 or x == n-1): continue
for i in range(t-1):
x = pow(x, 2, n)
if (x == 1): return 0
if (x == n-1): break
if (x != n-1): return 0
return 1
for s in stdin:
a, b = map(int, s.split())
r = 0
k = a//6
v = 1
while(v):
for n in (k*6+1, k*6+5):
# 為了節省時間,只檢測 6p+1, 6p-1
# 其實除了 5 以外, 5 的倍數也不必測
if(n < a): continue
if(n > b): # 超過上界
v = 0
break
r += isPrime(n)
k += 1
if(a <= 2 and b >= 2): r += 1
if(a <= 3 and b >= 3): r += 1
# 上面的檢測會遺漏 2, 3 在這裡補
print(r)
2020/04/09
[zerojudge] d984: 棄保效應
from sys import stdin
op = 'ABC'
for s in stdin:
f = [[i, int(c)] for i, c in enumerate(s.split())]
f.sort(key = lambda z: z[1])
t = f.pop(0)
f[0][1] += t[1]
f.sort(key = lambda z: -z[1])
print(op[f[0][0]])
2020/04/08
[zerojudge] a091: 今晚打老虎
import sys, bisect
'''
你如果把每個值都塞到 list
list 太長造成每個 insert , sort , pop 都很耗時
可以用一個 dict 來記錄每個值出現的次數
'''
f = [] # 要維護的 list
d = {} # 記錄每個值出現的次數
for s in sys.stdin:
if(s == '2\n'): # Query MAX
p = f[-1]
print(p)
d[p] -= 1
if(d[p] == 0): f.pop()
'''
印出尾部最大值
計數減一
計數為零才 pop()
'''
elif(s == '3\n'): # Query MIN
p = f[0]
print(p)
d[p] -= 1
if(d[p] == 0): f.pop(0)
'''
印出頭部最小值
計數減一
計數為零才 pop(0)
'''
else: # Insert
t = int(s.replace('1 ',''))
if(d.__contains__(t)): d[t] += 1
else: d[t] = 1
'''
計數不存在時設為 1
反之加 1
'''
if(d[t] == 1):
bisect.insort_left(f, t)
'''
如為新成員才 insert
利用 bisect.insort_left = insert and sort
'''
2020/04/05
[zerojudge] e974: 2. 座位安排 (Seats)
from sys import stdin
from collections import deque
r, c, n = map(int, stdin.readline().split())
h = deque([deque([x for x in range(i,i+c)]) for i in range(1, r*c+1, c)])
n -= 1
odd = even = n//2
even += n%2
h.rotate(odd % r)
for u in h:
u.rotate(even % c)
u = list(map(str, u))
print(' '.join(u))
2020/03/26
[zerojudge] b331: NOIP2013 2.表达式求值
import sys
from functools import reduce
import operator
def fn(x):
x = [int(c) for c in x.split('*')]
return(reduce(operator.mul, x, 1))
s = sys.stdin.readline().strip().split('+')
print(sum([fn(x) for x in s])%10000)
2020/03/25
[zerojudge] e942: pC. 數字排列
'''
一開始擔心記憶體不夠
使用索引值求全排列
將索引值對應的值印出
0.8s
'''
from sys import stdin, stdout
from itertools import permutations
ind = [0,1,2,3,4,5,6,7,8]
n = int(stdin.readline())
f = sorted(stdin.readline().strip().split(), key = int)
# 為了節省輸出時要轉回 str 的時間,這裡保留 str
p = ind[:n]
U = permutations(p)
for u in U: stdout.write(' '.join([f[i] for i in u]) + '\n')
#################################
# 直接全排列 0.3s
#
from sys import stdin, stdout
from itertools import permutations
n = int(stdin.readline())
f = sorted(stdin.readline().strip().split(), key = int)
U = permutations(f)
for u in U: stdout.write(' '.join(u) + '\n')
2020/03/22
[zerojudge] c463: apcs 樹狀圖分析 (Tree Analyses)
class node:
def __init__(self):
self.index = 0
self.parent = 0
self.height = 0
self.child = False
from sys import stdin
n = int(stdin.readline())
nodes = {k: node() for k in range(1, n+1)}
# 初始化節點
for i in range(1, n+1):
s = stdin.readline().strip()
nodes[i].index = i
if(s != '0'):
tmp = [int(x) for x in s.split()][1:]
nodes[i].child = True
for x in tmp: nodes[x].parent = i
# 依序讀入測資,紀錄每個 node 的屬性
root = [v for v in nodes.values() if v.parent == 0][0]
print(root.index)
# 尋找 root , root 沒有 parent
leaves = [v for v in nodes.values() if not v.child]
# 尋找 leaf , leaf 沒有 child
# 由 leaf 往上數,並記錄 height
for leaf in leaves:
cnt = 1
nxt = leaf.parent
while(1):
if(cnt <= nodes[nxt].height): break
nodes[nxt].height = cnt
'''
數到某一個 node 發現有 height
如果 cnt > height 表示這個深度較深,
繼續往上,反之脫離。
'''
nxt = nodes[nxt].parent
if(nxt == 0): break
# 繼續往上推
cnt += 1
ans = sum([v.height for v in nodes.values()])
# 加總每個節點的高度
print(ans)
2020/03/21
[zerojudge] b964: 第 1 題 成績指標
from sys import stdin
opt = ''
for s in stdin:
s = stdin.readline().strip()
f = sorted([int(x) for x in s.split()])
opt += ' '.join(map(str, f)) + '\n'
n = [x for x in f if x < 60]
if(n): opt += str(n[-1]) + '\n'
else: opt += 'best case\n'
n = [x for x in f if x >= 60]
if(n): opt += str(n[0]) + '\n'
else: opt += 'worst case\n'
print(opt.strip()) # 嚴格比對
[zerojudge] d828: Pascal's triangle's secret (II)
'''
依題意手算了幾個 n 發現是個 Fibonacci numbers
看到這種 n 很大,且要求取模輸出
猜想輸出的值大概會在 n 在某值時循環
google 發現是 Pisano period
網路上有求 Pisano period 的公式
此題我先算好 m = 10000, pisano = 15000
底下先建表,讀取測資後查表輸出
'''
from sys import stdin
f = [1,1,2,3,5,8]
pisano = 15000
for i in range(6, pisano):
t = (f[-1]+f[-2])%10000
f.append(t)
for s in stdin:
n = int(s) % pisano
print(f[n])
[zerojudge] e583: 11040 - Add bricks in the wall
from sys import stdin
N = int(stdin.readline())
for _ in range(N):
for __ in range(3):
s = stdin.readline()
# 前 3 行資料不重要
s4 = [int(x) for x in stdin.readline().split()]
s5 = [int(x) for x in stdin.readline().split()]
base = []
for i in range(len(s4)):
base.append(s5[i])
base.append((s4[i]-s5[i]-s5[i+1])//2)
base.append(s5[-1])
'''
關鍵在最下 2 層
最下層每 2 個數中要插入一個值
這個值 = (s4[i]-s5[i]-s5[i+1])//2
先把最下層每個數都求出
'''
r = [base]
for i in range(8):
tmp = []
for j in range(len(r[-1])-1):
tmp.append(r[-1][j]+r[-1][j+1])
r.append(tmp)
for z in r[::-1]: print(*z)
2020/03/20
[zerojudge] e799: p6. 資工系的浪漫
from sys import stdin
n, m = [int(c) for c in stdin.readline().split()]
ch = stdin.readline().strip() + ' '
for _ in range(n):
s = bin(int(stdin.readline()))[2:].zfill(m)
s = s.replace('1', ch).replace('0', '. ').strip()
print(s)
2020/03/19
[zerojudge] e929: pC. 分解質因數
import sys
import math
limit = 20000000
u = int(math.sqrt(limit))
sieve = [0, 0, 2, 3] + [1] * (u - 4)
prime = [2]
for i in range(3, u, 2):
if(sieve[i] == 0): continue
prime.append(i)
for j in range(i * i, u, i):
sieve[j] = 0
def fact(n):
r = []
k = math.sqrt(n)
for x in prime:
if(x > k): break
if(x > n): break
c = 0
while(n % x == 0):
c += 1
n //= x
if(c): r.append([x,c])
if(n > 1): r.append([n,1])
return r
def op(z):
if(z[1] == 1): return str(z[0])
return '{}^{}'.format(*z)
for s in sys.stdin:
n = int(s)
f = fact(n)
r = list(map(op, f))
print('{} = {}'.format(n, ' * '.join(r)))
2020/03/18
[zerojudge] e924: pC. 括號配對
from sys import stdin
chk = ['()','[]','<>','{}']
T = int(stdin.readline())
for _ in range(T):
s = stdin.readline().strip()
while(s):
p1 = len(s)
for z in chk: s = s.replace(z, '')
p2 = len(s)
if(p2 == p1): break
# p2 == p1 表示找不到成對的括號
print('N' if s else 'Y')
2020/03/06
[zerojudge] d563: 等值首尾和
from sys import stdin
from itertools import accumulate
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# https://docs.python.org/3/library/itertools.html#itertools.accumulate
f = [int(x) for x in stdin.readline().split()][1:]
a = set(accumulate(f))
b = set(accumulate(f[::-1]))
c = a & b
print(len(c))
'''
這題測資沒有斷行
所以 input 取 f[1:]
以 7 3 6 2 1 4 5 2
f = [3, 6, 2, 1, 4, 5, 2]
accumulate(f) = [3, 9, 11, 12, 16, 21, 23] # 從前面累計
accumulate(f[::-1]) = [2, 7, 11, 12, 14, 20, 23] # 從後面累計
a = set(accumulate(f)) = {3, 9, 11, 12, 16, 21, 23}
b = set(accumulate(f[::-1])) = {2, 7, 11, 12, 14, 20, 23}
c = a & b 是交集
print(len(c)) 交集的個數
'''
[zerojudge] e346. 區間和練習
import sys
from itertools import accumulate
opt = ''
while(1):
try:
s = sys.stdin.readline()
s = '0 ' + sys.stdin.readline()
q = [int(x) for x in s.split()]
q = list(accumulate(q))
m = int(sys.stdin.readline())
for i in range(m):
l, r = [int(x) for x in sys.stdin.readline().split()]
opt += '{}\n'.format(q[r]-q[l-1])
except: break
print(opt.strip())
[zerojudge] a007: 判斷質數
from sys import stdin
def isPrime(n):
'''
參考 http://www.csie.ntnu.edu.tw/~u91029/Prime.html
質數判定
'''
if(n in [2,3,5]): return 1
if(n%2 == 0): return 0
if(n%6 not in [1,5]): return 0
u = n - 1
t = 0
while(u % 2 == 0):
u >>= 1
t += 1
sprp = [2, 7, 61]
for sk in sprp:
a = sk % n
if (a == 0 or a == 1 or a == n-1): continue
x = pow(a, u, n)
if (x == 1 or x == n-1): continue
for i in range(t-1):
x = pow(x, 2, n)
if (x == 1): return 0
if (x == n-1): break
if (x != n-1): return 0
return 1
r = ['非質數', '質數']
for s in stdin:
v = isPrime(int(s))
print(r[v])
2020/03/04
[zerojudge] d387: 10235 - Simply Emirp
from sys import stdin
def isPrime(n):
'''
參考 http://www.csie.ntnu.edu.tw/~u91029/Prime.html
質數判定
'''
if(n == 2): return 1
if(n%2 == 0): return 0
if(n%6 not in [1,5]): return 0
u = n - 1
t = 0
while(u % 2 == 0):
u >>= 1
t += 1
sprp = [2, 7, 61]
for sk in sprp:
a = sk % n
if (a == 0 or a == 1 or a == n-1): continue
x = pow(a, u, n)
if (x == 1 or x == n-1): continue
for i in range(t-1):
x = pow(x, 2, n)
if (x == 1): return 0
if (x == n-1): break
if (x != n-1): return 0
return 1
ans = ['not prime.', 'prime.', 'emirp.']
for s in stdin:
s = s.strip()
sr = s[::-1]
v = isPrime(int(s))
# 先檢查 int(s) 是否為質數
if(v and sr != s):
# s 是質數才檢查 sr
v += isPrime(int(sr))
print('{} is {}'.format(s, ans[v]))
[zerojudge] a223: 10298 - Power Strings
from sys import stdin
import math
'''
題目說 字串長度 <= 1000000
所以先來建立一個質數表
'''
limit = 1000000
u = int(math.sqrt(limit))
sieve = [0, 0, 2, 3] + [1] * (u - 4)
prime = [2]
for i in range(3, u, 2):
if(sieve[i] == 0):
# sieve[i] 為 0 表示被篩掉了
continue
prime.append(i)
for j in range(i*i, u, i):
sieve[j] = 0
########
def fact(n): # 因數分解
r = []
k = math.sqrt(n)
for x in prime:
if(x > k): break
# 檢查到 n 的平方根
c = 0
while(n % x == 0):
c += 1
n //= x
if(c): r.append([x,c])
# c 是試除的次數
if(n > 1): r.append([n,1])
# 剩餘的數 > 1 必定是質因數
return r
def expand(v, i):
if(i == len(prt)): return
for h in range(prt[i][1]+1):
tmp = v
tmp *= prt[i][0] ** h
f.add(tmp)
expand(tmp, i+1)
for s in stdin: # 開始 input
s = s.strip()
if(s == '.'): break
n = len(s) # 字串長度
if(s[0] * n == s):
# 如果出現 aaaaa 直接輸出 5
print(n)
continue
prt = fact(n)
# 先對字串長度做質因數分解
# 如果 n = 6, fact(6) = [[2,1],[3,1]]
f = set()
expand(1, 0)
# 遞迴將 prt 展開為正因數
# fact(6) = [[2,1],[3,1]] = [1,2,3,6]
正因數表 = sorted(list(f))
'''
接下來要針對字串長度的正因數來比對
1 就不用了,上面檢查過了
'''
for 長度 in 正因數表[1:]:
檢查字串 = s[:長度]
倍數 = n // 長度
if(檢查字串 * 倍數 == s):
print(倍數)
break
[zerojudge] d713: 中位數
import sys
from heapq import *
# https://docs.python.org/zh-tw/3/library/heapq.html
heapL = []
heapR = []
'''
heapL 放 <= 中位數的值,
因為我取左半部,都會取最大值,所以我存入負數。
heapR 放 >= 中位數的值,
因為我取右半部,都會取最小值,所以我存入原數。
heappop : 從 heap 取出並回傳最小的元素
heappush : only push
heappushpop : push and pop
'''
heapify(heapL)
heapify(heapR)
# heapify() 將一個 list 轉成一個 heap
count = 0
# 讀取記數,判斷 element 數量奇偶
# 奇數時,讓左邊多一個
# 偶數時,讓兩邊一樣多
for s in sys.stdin: # 開始 input
n = int(s)
count += 1
if(count == 1):
heappush(heapL, -n)
print(n)
continue
# first element, 直接印出, 存入負值
# 直接 continue 讀取下一個值
largestL = -heapL[0]
# heapL[0] 是 heapL 的最小值,
# 加負號 = 左邊最大值
if(count % 2 == 0):
# element count 偶數時
if(n >= largestL):
heappush(heapR, n)
# 把 n 存入右邊,2 側數量相等
smallestR = heapR[0]
# 查詢 heapR[0] , 這是右邊的最小值
r = (largestL + smallestR) // 2
else:
heappushpop(heapL, -n)
# 把 n 存入左邊, 同時刪除 largestL
heappush(heapR, largestL)
# 把 largestL 存入右邊,2 側數量相等
smallestR = largestL
largestL = -heapL[0]
# 新的左側最大值
r = (largestL + smallestR) // 2
else:
# element count 奇數時
smallestR = heapR[0]
if(n > smallestR):
# 此時 n 要放在右邊
# 右邊多一個要移到左邊
heappush(heapL, -(smallestR))
# smallestR 直接塞左邊
heappushpop(heapR, n)
# 把 n 放右邊並刪除原本最小值
r = -(heapL[0])
# 左邊比右邊多一個, 最大的數就是中位數
else:
heappush(heapL, -(n))
# 直接把值塞左邊
r = -(heapL[0])
# 左邊比右邊多一個, 最大的數就是中位數
print(r)
[zerojudge] e080: read and write
import sys
mx = 200000
# 設定每次讀取的長度,請自行調整。
# 設太大會 MLE 太小會 TLE
sp = 0
# space 的位置,也是 x 的長度。
pr = 0
# 找到 space 會開啟列印狀態,
while(1):
tmp = sys.stdin.buffer.read(mx).decode()
# 每次讀取一段
本次讀取長度 = len(tmp)
if(pr):
print(tmp, end = '')
# 列印模式已打開,讀到的都要印出
else:
# 還沒開始列印
v = tmp.find(' ')
# 看看本次有沒有讀到 space
if(v == -1):
sp += mx
# 沒看到 space 先紀錄 x 的長度
else:
pr = 1
sp += v
print(tmp[v+1:], end = '')
# 有看到 space 先開啟列印模式
# 把 space 前的長度加到 sp
# 把 space 後面的字先印出
if(本次讀取長度 < mx): break
# 到檔尾了
print(' ', end = '') # y 印好了補個 space
sys.stdin.seek(0) # 倒回原點
while(sp):
tmp = sys.stdin.buffer.read(mx).decode()
本次讀取長度 = len(tmp)
本次列印長度 = min(sp, 本次讀取長度)
本次列印內容 = tmp[:本次列印長度]
print(本次列印內容, end = '')
sp -= 本次列印長度
[zerojudge] d366: 00294 - Divisors
from sys import stdin
import math
# 先用篩法建一小段質數
u = 100
sieve = [0, 0, 2, 3] + [1] * (u - 4)
prime = [2]
for i in range(3, u, 2):
if(sieve[i] == 0): continue
prime.append(i)
for j in range(i * i, u, i):
sieve[j] = 0
#######################
def isPrime(n):
'''
參考 http://www.csie.ntnu.edu.tw/~u91029/Prime.html
質數判定
'''
if(n == 2): return 1
if(n%2 == 0): return 0
if(n%6 not in [1,5]): return 0
u = n - 1
t = 0
while(u % 2 == 0):
u >>= 1
t += 1
sprp = [2, 7, 61]
for sk in sprp:
a = sk % n
if (a == 0 or a == 1 or a == n-1): continue
x = pow(a, u, n)
if (x == 1 or x == n-1): continue
for i in range(t-1):
x = pow(x, 2, n)
if (x == 1): return 0
if (x == n-1): break
if (x != n-1): return 0
return 1
def factorize(n):
# 因數分解
# 參考網路上的解法,非原創
if(isPrime(n)): return 1, n, 1
x_fixed = 2
cycle_size = 2
x = 2
factor = 1
while factor == 1:
count = 1
while count <= cycle_size and factor <= 1:
x = (x*x + 1) % n
factor = math.gcd(x - x_fixed, n)
count += 1
cycle_size *= 2
x_fixed = x
c = 0
while(n % factor == 0):
n //= factor
c += 1
return n, factor, c
def 計算因數(n):
if(n == 1): return 1
if(isPrime(n)): return 2
k = int(n ** 0.5) # 上限
r = 1
for x in prime:
if(x > k): break
c = 0
while(n % x == 0):
c += 1
n //= x
r *= (c + 1)
'''
先用建立好的一小段質數表試除
剩餘的用 factorize 分解
'''
while(n > 1):
n, y, z = factorize(n)
r *= (z + 1)
if(n == 1): break
return r
N = int(stdin.readline()) # 測資筆數
for i in range(N):
L, U = map(int, stdin.readline().split())
P, D = 0, 0
for j in range(L, U+1):
tmp = 計算因數(j)
if(tmp > D):
P, D = j, tmp
print('Between {} and {}, {} has a maximum of {} divisors.'.format(L, U, P, D))
2020/03/03
[zerojudge] c636: 十二生肖
import sys
ani = '鼠牛虎兔龍蛇馬羊猴雞狗豬'
for s in sys.stdin:
n = int(s)
if(n > 0): n = (n-1) % 12
else: n = n % 12
print(ani[n])
2020/03/02
[zerojudge] d120: 10699 - Count the factors
from sys import stdin
import math
'''
題目說 n <= 1000000
而 n 的質因數 <= sqrt(n)
所以先來建立一個質數表
'''
limit = 1000000
u = int(math.sqrt(limit))
sieve = [0, 0, 2, 3] + [1] * (u - 4)
prime = [2]
for i in range(3, u, 2):
if(sieve[i] == 0): continue
# sieve[i] 為 0 表示被篩掉了
prime.append(i)
for j in range(i*i, u, i):
sieve[j] = 0
# 你可以 print(prime) 來核對
# print(prime)
def 質因數計次(n):
tmp = n
res = 0
k = math.sqrt(n)
for pr in prime:
if(pr > k): break
# 檢查到 n 的平方根
c = 0
while(tmp%pr == 0):
c = 1
tmp //= pr
res += c
# c 是試除符合
if(tmp > 1): res += 1
# 剩餘的數 > 1 必定是質因數
return '{} : {}'.format(n, res)
opt = []
for s in stdin:
n = int(s)
if(n == 0): break
opt.append(質因數計次(n))
print('\n'.join(opt))
# 一次輸出
2020/03/01
[zerojudge] d139: Compressed String
from sys import stdin
for s in stdin:
s = s.strip()
ans = ''
while(s):
原長度 = len(s)
c = s[0] # 第一個字元
s = s.lstrip(c)
新長度 = len(s)
長度差 = 原長度 - 新長度
if(長度差 < 3):
ans += c * 長度差
else:
ans += '{}{}'.format(長度差, c)
print(ans)
2020/02/29
[zerojudge] a565: 2.p&q的邂逅
from sys import stdin
T = int(stdin.readline())
for _ in range(T):
s = stdin.readline().replace('.', '')
# 先將 . 去掉
原長度 = x = len(s)
while(x):
s = s.replace('pq', '')
# 把 pq 抽走
y = len(s)
if(y == x): break
x = y
print((原長度-x)//2)
[zerojudge] e446: 排列生成
import sys
a = int(input()) # 只有一行輸入
f = [str(c) for c in range(1, a+1)]
# 輸入 3 --> ['1', '2', '3']
d = permutations(f)
'''
利用 permutations 求全排列
print(list(d)) 可以觀察 d
[('1', '2', '3'), ('1', '3', '2'),
('2', '1', '3'), ('2', '3', '1'),
('3', '1', '2'), ('3', '2', '1')]
'''
for u in d:
sys.stdout.write(' '.join(u) + '\n')
[zerojudge] d518: 文字抄寫 II
import sys
opt = ''
for s in sys.stdin:
w = int(s)
c = 1 # counter init
f = [{} for i in range(26)]
# 每個字母獨立一個 dict
for i in range(w):
s = sys.stdin.readline()
ch = ord(s[0]) - 97
# 讀入字串的第一個字母的 ascii 值
# 在 f 的位置 f[0] 就是 a 的字典
if(f[ch].__contains__(s)):
opt += 'Old! {}\n'.format(f[ch][s])
# 字典已有此字
else:
opt += 'New! {}\n'.format(c)
f[ch][s] = c
# 字典沒有這個字,將 c 紀錄起來。
c += 1
sys.stdout.write(opt.strip())
# 一次印出
[zerojudge] d057: 11494 - Queen
import sys
for s in sys.stdin:
if(s == '0 0 0 0\n'): break
x1, y1, x2, y2 = [int(z) for z in s.split()]
m, n = abs(x1-x2), abs(y1-y2)
r = 2
if(m + n == 0): r = 0 # 同一點
elif(m * n == 0): r = 1 # 同一軸
elif(m == n): r = 1 # 同斜率
print(r)
[zerojudge] d596: 1. 猜九宮格裡的地雷
import sys
# 把每個九宮格的鄰居先建表
d = ({'1': set(['2','4']),
'2': set(['1','3','5']),
'3': set(['2','6']),
'4': set(['1','5','7']),
'5': set(['2','4','6','8']),
'6': set(['3','5','9']),
'7': set(['4','8']),
'8': set(['5','7','9']),
'9': set(['6','8'])})
w = int(sys.stdin.readline())
for i in range(w):
a, b, c = sys.stdin.readline().strip().split()
# d[a] 是可能地雷, d[b] 及 d[c] 是排除的
r = sorted(list(d[a] - d[b] - d[c]))
# 使用減法可以省去很多判斷
# r 為空,表示矛盾。
if r: print(*r)
else: print('Empty')
2020/02/28
[zerojudge] a010: 因數分解
# a010 因數分解 python
import sys
import math
'''
題目說 n <= 1000000
而 n 的質因數 <= sqrt(n)
所以先來建立一個質數表
'''
limit = 1000000
u = int(math.sqrt(limit))
sieve = [0, 0, 2, 3] + [1] * (u - 4)
prime = [2]
for i in range(3, u, 2):
if(sieve[i] == 0):
# sieve[i] 為 0 表示被篩掉了
continue
prime.append(i)
for j in range(i * i, u, i):
sieve[j] = 0
# 你可以 print(prime) 來核對
# print(prime)
def fact(n):
r = []
k = math.sqrt(n)
for x in prime:
if(x > k): break
# 檢查到 n 的平方根
c = 0
while(n % x == 0):
c += 1
n //= x
if(c): r.append([x,c])
# c 是試除的次數
if(n > 1): r.append([n,1])
# 剩餘的數 > 1 必定是質因數
return r
def op(z):
if(z[1] == 1): return str(z[0])
return '{}^{}'.format(z[0], z[1])
# 主程式
for s in sys.stdin:
n = int(s)
f = fact(n) # 先分解
# print(f) 看結果對不對
r = list(map(op, f))
print(' * '.join(r))
'''
假設 n = 100
fact(n) = [[2, 2], [5, 2]]
r = ['2^2', '5^2']
'''
[zerojudge] e700: 星座
import sys
for s in sys.stdin:
m, d = s.strip().split('/')
md = m.rjust(2, '0') + d.rjust(2, '0')
if(md < '0121'): print('摩羯座')
elif(md >= '0121' and md <= '0219'): print('水瓶座')
elif(md >= '0220' and md <= '0320'): print('雙魚座')
elif(md >= '0321' and md <= '0420'): print('牡羊座')
elif(md >= '0421' and md <= '0521'): print('金牛座')
elif(md >= '0522' and md <= '0621'): print('雙子座')
elif(md >= '0622' and md <= '0722'): print('巨蟹座')
elif(md >= '0723' and md <= '0821'): print('獅子座')
elif(md >= '0822' and md <= '0923'): print('處女座')
elif(md >= '0924' and md <= '1023'): print('天秤座')
elif(md >= '1024' and md <= '1122'): print('天蠍座')
elif(md >= '1123' and md <= '1222'): print('射手座')
elif(md >= '1223'): print('摩羯座')
訂閱:
文章 (Atom)