aacord’s memo

abcを中心にpythonで解いた問題のメモ、整理をしています。緑になった。

abc 172,173 感想

172 4完 パフォ1421
173 4完 パフォ1319
まあ失敗ではないけど大成功でもない感じ。次で水色なりたいね。
172は包除原理の一般法則を知らなかったのが原因。Fは難しかった。

#172 E
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

n,m = map(int,readline().split())
mod = 10**9+7

class Combination:
    def __init__(self, n_max, mod=10**9+7):
        self.mod = mod
        f = 1
        self.fac = fac = [f]
        for i in range(1, n_max+1):
            f = f * i % mod
            fac.append(f)
        f = pow(f, mod-2, mod)
        self.facinv = facinv = [f]
        for i in range(n_max, 0, -1):
            f = f * i % mod
            facinv.append(f)
        facinv.reverse()

    def __call__(self, n, r):
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n-r] % self.mod

    def C(self, n, r):
        if not 0 <= r <= n: return 0
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n-r] % self.mod

    def P(self, n, r):
        if not 0 <= r <= n: return 0
        return self.fac[n] * self.facinv[n-r] % self.mod
      
f = Combination(m, mod)
ans = 0
for k in range(m+1):
  chk = f.C(n,k)*f.P(m,k)*pow(f.P(m-k,n-k),2,mod)%mod
  ans += pow(-1,k)*chk
  ans %= mod
print(ans)

173 はEみたいな問題が苦手。mod 取った後に大小比較をしていたり、一つだけ正の数が含まれているケースに何故かやられていた。要復習。
c は縦と横に1列ずつ追加して 2**7*2**7の全探索をして答えを4で割った。D は最初二分探索なにおいを感じたけど、貪欲に考えたら、解説と同じような選び方が最適な気がして投げたら通った。

#173 C
import sys
input = sys.stdin.readline
h,w,k = map(int,input().split())
s = 0
a = [[0]*(w+1)]
for i in range(h):
  ar = input().rstrip()
  for i in ar:
    if i == '#':
      s += 1
  a.append([0]+list(ar))
  
ans = 0
for i in range(2**(h+1)):
  for j in range(2**(w+1)):
    chk = s
    for num,ai in enumerate(a):
      if i>>num&1:
        for aa in ai:
          if aa == '#':
            chk -= 1
      else:
        for bb in range(w+1):
          if j>>bb&1 and ai[bb] == '#':
            chk -= 1
    if chk == k:
      ans += 1
print(ans//4)

#173 D
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
n = int(readline())
a = list(map(int,readline().split()))
a.sort(reverse=True)

k = n//2
if n % 2 == 1:
  print(sum(a[:k])*2-a[0]+a[k])
else:
  print(sum(a[:k])*2-a[0])