Problem:
 Score : 400 points    Problem Statement You are going out for a walk, when you suddenly encounter a monster. Fortunately, you have N katana (swords), Katana 1 , Katana 2 , … , Katana N , and can perform the following two kinds of attacks in any order:   Wield one of the katana you have. When you wield Katana i  (1 ≤ i ≤ N) , the monster receives a_i points of damage. The same katana can be wielded any number of times.  Throw one of the katana you have. When you throw Katana i  (1 ≤ i ≤ N) at the monster, it receives b_i points of damage, and you lose the katana. That is, you can no longer wield or throw that katana.   The monster will vanish when the total damage it has received is H points or more. At least how many attacks do you need in order to vanish it in total?      Constraints  1 ≤ N ≤ 10^5  1 ≤ H ≤ 10^9  1 ≤ a_i ≤ b_i ≤ 10^9  All input values are integers.         Input Input is given from Standard Input in the following format:  N  H  a_1  b_1  :  a_N  b_N       Output Print the minimum total number of attacks required to vanish the monster.        Sample Input 1 1 10
3 5      Sample Output 1 3  You have one katana. Wielding it deals 3 points of damage, and throwing it deals 5 points of damage. By wielding it twice and then throwing it, you will deal 3 + 3 + 5 = 11 points of damage in a total of three attacks, vanishing the monster.       Sample Input 2 2 10
3 5
2 6      Sample Output 2 2  In addition to the katana above, you also have another katana. Wielding it deals 2 points of damage, and throwing it deals 6 points of damage. By throwing both katana, you will deal 5 + 6 = 11 points of damage in two attacks, vanishing the monster.       Sample Input 3 4 1000000000
1 1
1 10000000
1 30000000
1 99999999      Sample Output 3 860000004       Sample Input 4 5 500
35 44
28 83
46 62
31 79
40 43      Sample Output 4 9

Solution (Python):
n, h = map(int, input().split())
arr = []
for _ in range(n) :
    a,b = map(int, input().split())
    arr.append((a,-1))
    arr.append((b,1))

cnt = 0
ans = 10**9 + 100
for p in reversed(sorted(arr)) :
    if p[1] == -1 :
        
        ans = min(ans, cnt + (h+p[0]-1)//p[0])
        break
    elif p[1] == 1 and h>0 :
        
        h -= p[0]
        cnt += 1
        if h <= 0 :
            h = 0
            ans = min(ans, cnt)

print(ans)

Solution (Python):
n, h = map(int, input().split())
arr = []
for _ in range(n) :
    a,b = map(int, input().split())
    arr.append((a,-1))
    arr.append((b,1))

cnt = 0
ans = 10**9 + 100
for p in sorted(arr)[::-1] :
    if p[1] == -1 :
        
        ans = min(ans, cnt + (h+p[0]-1)//p[0])
        break
    elif p[1] == 1 and h>0 :
        
        h -= p[0]
        cnt += 1
        if h <= 0 :
            h = 0
            ans = min(ans, cnt)

print(ans)

Solution (Python):
n, h = map(int, input().split())
arr = []
for _ in range(n) :
    a,b = map(int, input().split())
    arr.append((a,-1))
    arr.append((b,1))

arr.sort()
arr.reverse()

cnt = 0
ans = 10**9 + 100
for p in arr :
    if p[1] == -1 :
        
        ans = min(ans, cnt + (h+p[0]-1)//p[0])
        break
    elif p[1] == 1 and h>0 :
        
        h -= p[0]
        cnt += 1
        if h <= 0 :
            h = 0
            ans = min(ans, cnt)

print(ans)

Solution (Python):
n, h = map(int, input().split())
arr = []
for _ in range(n) :
    a,b = map(int, input().split())
    arr.append((a,-1))
    arr.append((b,1))

arr.sort()
arr.reverse()

cnt = 0
ans = 10**9 + 100
for p in arr :
    if p[1] == -1 :
        
        ans = min(ans, cnt + (h+p[0]-1)//p[0])
    elif p[1] == 1 and h>0 :
        
        h -= p[0]
        cnt += 1
        if h <= 0 :
            h = 0
            ans = min(ans, cnt)

print(ans)

Solution (Python):
import math

if __name__ == '__main__':
    N, H = map(int, input().split())
    a = []
    b = []
    for _ in range(N):
        tmp_a, tmp_b = map(int, input().split())
        a.append(tmp_a)
        b.append(tmp_b)

    max_a = max(a)
    ans = 0
    b = sorted(b, reverse=True)
    damage = 0
    for i in range(N):
        if max_a < b[i]:
            damage += b[i]
            ans += 1
        else:
            break

        if H <= damage:
            print(ans)
            exit()

    ans += math.ceil((H - damage) / max_a)

    print(ans)

Solution (Python):
def solve():
    N, HP  = map(int, input().split())
    score = 0

    f = []
    n = []
    for i in range(N):
        a, b = map(int, input().split())
        f.append(a)
        n.append(b)

    
    lastf = max(f)
    lastid = f.index(lastf)
    lastn = n[lastid]
    n.sort(reverse = True)


    for i in range(len(n)):
        mn = n[0]
        id = 0
        if lastf < mn:
            HP -= mn
            n.pop(id)
            score += 1
            if HP <= 0:
                return score
        else:
            break

    score += -(-HP // lastf)
    return score


print(solve())

Solution (Python):

import math
N, H = map(int, input().split())
a = [0] * N
b = [0] * N
for i in range(N):
    a[i], b[i] = map(int, input().split())

b.sort(reverse=True)
m = max(a)
s = 0
for i in range(N):
    b[i] = max(b[i], m)
    s += b[i]
    if s >= H:
        print(i + 1)
        break
else:
    print(N + math.ceil((H - s) / m))

Solution (Python):

import math
N, H = map(int, input().split())
a = [0] * N
b = [0] * N
for i in range(N):
    a[i], b[i] = map(int, input().split())

b.sort(reverse=True)
m = max(a)
s = [0]
for i in range(N):
    b[i] = max(b[i], m)
    s.append(s[-1] + b[i])
    if s[-1] >= H:
        print(i + 1)
        break
else:
    print(max(N + 1, math.ceil((H - sum(b)) / m) + N))

Solution (Python):

N,H = map(int,input().split())

a = []
b = []
finish = 0

for i in range(1,N+1):
    elem1, elem2 = map(int,input().split())
    a.append(elem1)
    b.append(elem2)


b = sorted(b, key=int, reverse=True)

maxB = max(b)
maxA = max(a)
sum = maxB
b.remove(maxB)
count = 1
for elem in b:
    if elem > maxA and sum < H:
        sum = sum + elem
        count += 1
    if sum >= H:
        finish = 1
        break



if finish == 0:
    dev = int((H - sum)/maxA)
    count = count + dev
    sum = sum + dev * maxA
    if sum < H:
        count += 1

print(count)

Solution (Python):
import sys
from collections import defaultdict, Counter
from itertools import product, groupby, count, permutations, combinations
from math import pi, sqrt, floor
from collections import deque
from bisect import bisect, bisect_left, bisect_right
from string import ascii_lowercase
from functools import lru_cache, reduce
from operator import xor
from heapq import heappush, heappop
INF = float("inf")
sys.setrecursionlimit(10**7)


dy4, dx4 = [0, -1, 0, 1], [1, 0, -1, 0]


def inside(y: int, x: int, H: int, W: int) -> bool: return 0 <= y < H and 0 <= x < W
def ceil(a, b):return (a + b - 1) // b


def solve(N, H, a_b):
    max_a = -1
    for a, b in a_b:
        max_a = max(max_a, a)

    good_b = []
    for a, b in a_b:
        if b >= max_a:
            good_b.append(b)

    ans = 0
    for b in sorted(good_b, reverse=True):
        ans += 1
        H -= b
        if H <= 0:
            return ans

    return ans + ceil(H, max_a)


def main():
    N, H = map(int, input().split())
    l = []
    for _ in range(N):
        a, b = map(int, input().split())
        l.append((a, b))
    print(solve(N, H, l))


if __name__ == '__main__':
    main()

Solution (Python):

import math
n, h = map(int, input().split())
l = []
ans = 0

for tmp in range(n):
    a, b = map(int, input().split())
    l.append((a,b))

factor = sorted(l, key=lambda tmp:tmp[1])
max_a = max(l, key=lambda tmp:tmp[0])
while h > 0:
    if len(factor) != 0:
        max_b = factor[-1]
    else:
        max_b = (-1,-1)
    if max_a[0] < max_b[1]:
        h -= max_b[1]
        factor.pop()
        ans += 1
    else:
        ans += math.ceil(h/max_a[0])
        h -= max_a[0]*math.ceil(h/max_a[0])
print(ans)

Solution (Python):
n, h = map(int, input().split())
a, b = zip(*(tuple(map(int, input().split())) for _ in range(n)))
m = max(a)
c = 0
for v in sorted(b)[::-1]:
    if h<=0 or v<m:
        break
    h -= v
    c += 1
print(c + (max(0,h)+m-1)//m)

Solution (Python):
import math

n, h= map(int, input().split())
a = []
b = []

for i in range(n):
   a_tmp, b_tmp = map(int, input().split())
   a.append(a_tmp)
   b.append(b_tmp)

maxa = max(a)
b.sort()
b.reverse()

cnt = 0

for i in b:
   if i >= maxa:
      h -= i
      cnt += 1
      if h <= 0:
         break

if h > 0:
   cnt += math.ceil(h/maxa)

print(cnt)

Solution (Python):
import sys,collections,math
from operator import itemgetter
def Is(): return [int(x) for x in sys.stdin.readline().split()]

n,h = Is()
katanas = []
for i in range(n):
    katanas.append(Is())

katanas = sorted(katanas,reverse=True)
strongest = katanas[0]
katanas = sorted(katanas,reverse=True,key=itemgetter(1))
turns = 0
for katana in katanas:
    if katana[1] >= strongest[0]:
        turns += 1
        h -= katana[1]
        if h <= 0:
            print(turns)
            exit()
    else:
        break
turns += math.ceil(h/strongest[0])
print(turns)

Solution (Python):
def i2():
 return [int(i) for i in input().split()]

[n,h]=i2()
a=[]
for i in range(n):
 b=i2()
 a+=[[b[0],0],[b[1],1]]
a.sort()
a=a[::-1]
i=0
c=0
while a[i][1]==1 and h>0:
 h-=a[i][0]
 c+=1
 i+=1

if h>0:
 c+=h//a[i][0]
 if h%a[i][0]:c+=1
print(c)

Solution (Python):
import math

N,H = [int(i) for i in input().split()]

A = list()
B = list()

for i in range(N):
    a,b = [int(i) for i in input().split()]
    A.append(a)
    B.append(b)

maxA = max(A)
B.sort()
B.reverse()

cnt = 0
for i in B:
    if i > maxA:
        H = H - i
        cnt = cnt + 1
        if H <= 0:
            break

if H > 0:
    cnt = cnt + math.ceil(H/maxA)

print(cnt)

Solution (Python):
import sys
import math

N,H = map(int,input().split(" "))
a = []
b = []
for i in range(N):
    temp_a,temp_b = map(int,input().split(" "))
    a.append(temp_a)
    b.append(temp_b)
a.sort(key=None,reverse=True)
b.sort(key=None,reverse=True)
ans = 0


b2 = filter(lambda x: x>a[0],b)
b2 = list(b2)

for i in range(len(b2)):
    H -= b[i]
    ans += 1
    if H<=0:
        print(ans)
        sys.exit() 

ans += math.ceil(H/a[0])
print(ans)

Solution (Python):


import math
import sys

def main(argv):
    line = sys.stdin.readline()
    while line:
        N, H = map(lambda i: int(i), line.rstrip("\n").split(" "))
        attackes = []
        for i in xrange(N):
            a, b = map(
              lambda i: int(i), sys.stdin.readline().rstrip("\n").split(" "))
            attackes.append((i, a, "A"))
            attackes.append((i, b, "B"))

        max_a = max(
          filter(lambda t: t[2] == "A", attackes), key=lambda x: x[1])
        max_ab = attackes[max_a[0] * 2 + 1]

        hit = 0
        for t in sorted(attackes, key=lambda x: x[1], reverse=True):







            if t[0] == max_a[0] and t[1] == max_a[1] and t[2] == max_a[2]:
                break

            H -= t[1]
            hit += 1

            if H <= 0:
                break
        
        if H > 0:
            q, r = divmod(H, max_a[1])
            hit += q
            if r > 0:
                hit += 1
        print hit

        line = sys.stdin.readline()

if __name__ == "__main__":
    main(sys.argv)

Solution (Python):
import math

N, H = map(int, input().split())
A = []
B = []

for _ in range(N):
    a, b = map(int, input().split())
    A.append(a)
    B.append(b)

a_max = max(A)

B = sorted([x for x in B if x > a_max], reverse = True)

attack = 0

for damage in B:
    H -= damage
    attack += 1
    if H <= 0:
        break

if H > 0:
    attack += math.ceil(H / a_max)

print(attack)

Solution (Python):
import math

N, H = map(int, input().split())
sword_list = [list(map(int, input().split())) for i in range(N)]

a_sorted_sword = sorted(sword_list, key=lambda x:x[0], reverse=True)
a_max = a_sorted_sword[0][0]
b_sorted_sword = sorted(sword_list, key=lambda x:x[1], reverse=True)

count = 0
for sword in b_sorted_sword:
    if sword[1] < a_max:
        break
    H -= sword[1]
    count += 1
    if H <= 0:
        break

if not H <= 0:
    count += math.ceil(H / a_max)

print(count)

Solution (Python):



def solve():
    n, hp = map(int, input().split())
    swing_damage_list = []
    throw_damege_list = []
    
    for _ in range(n):
        swing_damage, throw_damage = map(int, input().split())
        swing_damage_list.append(swing_damage)
        throw_damege_list.append(throw_damage)

    swing_damage_list.sort()
    throw_damege_list.sort()
    max_swing_damage = swing_damage_list[-1]

    will_throw_list = [damage for damage in throw_damege_list if damage > max_swing_damage]
   
    all_damage = sum(will_throw_list) 
    answer = len(will_throw_list)
    if all_damage > hp:
       for damage in will_throw_list:
            if all_damage - damage < hp:
                print(answer)
                return
            all_damage -= damage
            answer -= 1
    else:
        print(answer + ((hp - all_damage) + (max_swing_damage - 1)) // max_swing_damage)

if __name__=="__main__":
    solve()

Solution (Python):
from math import ceil


def solve(h, aa, bb):
    max_a = max(aa)
    i = 0
    for b in sorted(bb, reverse=True):
        if b <= max_a:
            break
        i += 1
        h -= b
        if h <= 0:
            return i
    return i + ceil(h / max_a)


n, h = map(int, input().split())
aa, bb = [], []
for _ in range(n):
    a, b = map(int, input().split())
    aa.append(a)
    bb.append(b)

print(solve(h, aa, bb))

Solution (Python):
from math import ceil


def solve(h, aa, bb):
    max_a = max(aa)
    i = 0
    for b in sorted(bb, reverse=True):
        if b <= max_a:
            break
        i += 1
        h -= b
        if h <= 0:
            return i
    return i + ceil(h / max_a)


n, h = map(int, input().split())
aa, bb = zip(*(map(int, input().split()) for _ in range(n)))

print(solve(h, aa, bb))

Solution (Python):
from bisect import bisect_left, bisect
from itertools import accumulate
from math import ceil


def solve(h, aa, bb):
    max_a = max(aa)
    bs = sorted(bb)
    i = bisect(bs, max_a)
    if i == n:
        return ceil(h / max_a)
    bba = list(accumulate(reversed(bs[i:])))
    remain = h - bba[-1]
    if remain <= 0:
        return bisect_left(bba, h) + 1
    return ceil(remain / max_a) + len(bba)


n, h = map(int, input().split())
aa, bb = zip(*(map(int, input().split()) for _ in range(n)))

print(solve(h, aa, bb))

Solution (Python):
import sys
import heapq
import time
from math import *

def get_read_func(fileobject):
    if fileobject == None :
        return raw_input
    else:
        return fileobject.readline

def main():
    if len(sys.argv) > 1:
        f = open(sys.argv[1])
    else:
        f = None
    read_func = get_read_func(f);
    input_raw = read_func().strip().split()
    [N, H] = [long(input_raw[0]), long(input_raw[1])]
    a_list = []
    b_list = []
    for i in range(N):
        input_raw = read_func().strip().split()
        [a, b] = [-long(input_raw[0]), -long(input_raw[1])]
        heapq.heappush(a_list, (a, i))
        heapq.heappush(b_list, (b, i))
    (max_a, max_a_i) = a_list[0]
    count = 0
    while (H > 0):
        if len(b_list) > 0:
            (max_b, max_b_i) = b_list[0]
        else:
            max_b = 0
        if -max_a >= -max_b:
            attack_num = (H ) / (-max_a)
            attack_num += (1 if ( H % (-max_a) >0 ) else 0)
            H += attack_num  * max_a
            count += attack_num
            
        
        else:
            heapq.heappop(b_list)
            H += max_b
            count += 1
            
        '''
        elif H + max_b <= 0:
            heapq.heappop(b_list)
            H += max_b
            count += 1
            print "max_a_i == max_b_i and max b can ",H, count
        else:
            attack_num = (H  + max_b) / (-max_a)
            attack_num += 1 if ( ((H + max_b)  % (-max_a)) >0 ) else 0
            H += attack_num * max_a
            count += attack_num
            print "max_a_i == max_b_i and max b cant ", H, count
        '''
    print count;

if __name__ == '__main__':
    main()

Solution (Python):















[N, H] = map(int, raw_input().split())



arrayA = []
arrayB = []

for i in range(N):
    [Ai, Bi] = map(int, raw_input().split())
    arrayA.append(Ai)
    arrayB.append(Bi)

arrayA.sort()
arrayB.sort()
arrayA.reverse()
arrayB.reverse()

count = 0

while H > 0:
    maxAi = arrayA[0]
    if len(arrayB) > 0:
        maxBi = arrayB[0]
    else:
        maxBi = 0
        
    if maxBi > maxAi:
        maxDmg = arrayB.pop(0)
        H = H -maxDmg
        count = count +1
    else:
        maxDmg = maxAi
        if maxDmg < H:
            count = count + (H / maxDmg)
            H = H % maxDmg
        else:
            count = count +1
            H = H -maxDmg



print count

Solution (Python):
from bisect import bisect_left
from itertools import accumulate, takewhile
from math import ceil


def solve(h, aa, bb):
    max_a = max(aa)
    bba = list(accumulate(takewhile(lambda x: x > max_a, sorted(bb, reverse=True))))
    if not bba:
        return ceil(h / max_a)
    remain = h - bba[-1]
    if remain <= 0:
        return bisect_left(bba, h) + 1
    return ceil(remain / max_a) + len(bba)


n, h = map(int, input().split())
aa, bb = zip(*(map(int, input().split()) for _ in range(n)))

print(solve(h, aa, bb))

Solution (Python):
import math

Num,HP = (map(int,input().split()))


CKatanaMax = 0
katanas = []

for _ in range(Num):
    a,b = map(int,input().split())
    CKatanaMax = max(CKatanaMax,a)
    katanas.append(b)

Tkatanas = sorted([x for x in katanas if x > CKatanaMax],reverse=True)

attake = 0
for Tkatana in Tkatanas:
    HP -= Tkatana
    attake += 1
    if HP <= 0:
        break
else:
    attake += math.ceil(HP/CKatanaMax)
print(attake)

Solution (Python):
n, h = map(int, input().split())
a = []
b = []
amax = 0
for i in range(n):
  ai, bi = map(int, input().split())
  if amax < ai:
    amax = ai
  a.append(ai)
  b.append(bi)

b = [b[j] for j in range(n) if b[j] > amax]
sumb = sum(b)
if sumb >= h:
  s = 0
  b = sorted(b)
  c = 0
  while s < h:
    s += b[-1]
    b.pop(-1)
    c += 1
  print(c)
else:
  print((h-sumb)//amax+((h-sumb)%amax!=0) + len(b))

Solution (Python):
N, H = [int(i) for i in input().split()]
ken_a = 0
ken_b = []
for _ in range(N):
    a,b = input().split()
    if int(a) >= H or int(b) >= H:
        print(1)
        quit()
    if ken_a < int(a):
        ken_a = int(a)
    ken_b.append(int(b))
res = 0
for b_ in sorted(ken_b,reverse=True):
    if b_ > ken_a:
        H = H - b_
        res += 1
        if H <= 0:
            print(res)
            quit()

res = res + (H//ken_a)
if H%ken_a != 0:
    res += 1
print(res)

Solution (Python):
from math import ceil

line = input().split(" ")
N = int(line[0])
H = int(line[1])

a = []
b = []

for _ in range(N):
    line = input().split(" ")
    a.append(int(line[0]))
    b.append(int(line[1]))

a.sort(reverse=True)
b.sort(reverse=True)

ret = 0
for x in b:
    if x<a[0]:
        break
    H -= x
    ret += 1
    if H<=0:
        break

if H>0:
    ret += ceil(H/a[0])

print(ret)

Solution (Python):
n, h = [int(x) for x in input().split()]
a = []
b = []
for _ in range(n):
    x, y = [int(x) for x in input().split()]
    a.append(x)
    b.append(y)

l = list(zip(a, b))

a.sort()
b.sort(reverse=True)
p = a[-1]

c = 0
d = 0
for y in b:
    if y < p:
        break
    if d >= h:
        print(c)
        exit()
    c += 1
    d += y

if (h - d) % p == 0:
    c += ((h - d) // p)
else:
    c += ((h - d) // p + 1)
print(c)

Solution (Python):

import math
N, H = map(int, input().split())
A = []
B = []
AB = []

for n in range(N):
    a, b = map(int, input().split())
    A.append(a)
    B.append(b)
    AB.append((a,b))



amax = max(A)
bmax = max(B)

B.sort(reverse=True)
i = 1
cnt = 1
H -= bmax

while H > 0:
    
    if i < N and B[i] > amax:
        cnt += 1
        H -= B[i]
        i += 1
    else:
        cnt += math.ceil(H/amax)
        
        H -= math.ceil(H/amax) * amax
        

print(cnt)

Solution (Python):

import math
N, H = map(int, input().split())
th = []
sl_max = 0
for i in range(N):
    s, t = map(int, input().split())
    sl_max = max(sl_max, s)
    th.append(t)
turn = 0
thdec = sorted(th, reverse=True)

for i in range(len(thdec)):
    if thdec[i] >= sl_max:
        H -= thdec[i]
        turn += 1
        if H <= 0:
            break
    else:
        break

if H > 0:
    turn += math.ceil(H / sl_max)

print(turn)

Solution (Python):
import numpy as np
n, h =[int(i) for i in input().split()]
a = np.empty(n)
b = np.empty(n)
for i in range(n):
    a[i], b[i] = [int(i) for i in input().split()]
sort_b = np.sort(b)
max_a = np.max(a)
b_big = sort_b[sort_b>max_a]
b_sum = np.sum(b_big)
if b_sum >= h:
    ret = np.sum(b_big[::-1].cumsum() <h) + 1 
else:
    ret = b_big.shape[0]
    ret += np.ceil((h -b_sum)/max_a)
print(int(ret))

Solution (Python):
n, h = map(int, raw_input().split())
throw = []
hit = []
for i in range(0, n): 
    ai, bi = map(int, raw_input().split())
    throw += [bi]
    hit += [ai]
throw.sort(reverse = True)
hit.sort(reverse = True)

ans = 0 
hth = 0 

for i in range(0, n): 
    if(throw[i] < hit[0]):
        break
    if (hth >= h): 
        break
    ans += 1
    hth += throw[i]
if (h - hth > 0): 
    ans += (h - hth + hit[0] - 1) // hit[0]
print ans

Solution (Python):
from math import ceil
import numpy as np
[n, h] = list(map(int, input().split()))
sword = []
for _ in range(n):
    sword.append(list(map(int, input().split())))
if n > 1:
    sword.sort(key=lambda x:x[1])
    cut = max(sword, key=lambda x:x[0])
    sword.remove(max(sword, key=lambda x:x[0]))
    sword.reverse()
    counter = 0
    for i in sword:
        if i[1] < cut[0]:
            break
        h -= i[1]
        counter += 1
        
        if h <= 0:
            break
    if h > 0:
        h -= cut[1]
        counter += 1
        if h > 0:
            counter += int(ceil(h / float(cut[0])))
    print(counter)
else:
    print(int(ceil((h - sword[0][1]) / sword[0][0])) + 1)

Solution (Python):
N, H = list(map(int,input().split()))
a = 0
b = [0]
for i in range(N):
    A = list(map(int,input().split()))
    a = max(a,A[0])
    b += [A[1]]
b = sorted(b)[::-1]
for i in range(N+1):
    if(H<=0):
        break
    if (b[i] > a):
        H -= b[i]
    else:
        i += int(H/a)+(0!=H%a)
        break
print(i)

Solution (Python):
import math
n, h = map(int, input().split())
a_max = 0
b_list = []
for i in range(n):
    a, b = map(int, input().split())
    a_max = max(a_max, a)
    b_list.append(b)
b_list = sorted(b_list, reverse=True)
count = 0
flag = 0
for i in range(len(b_list)):
    if a_max < b_list[i]:
        h -= b_list[i]
        count += 1
    else:
        flag = 1
        count += math.ceil(h/a_max)
        break
    if h <= 0:
        flag = 1
        break
if flag == 0:
    count += math.ceil(h/a_max)
print(count)

Solution (Python):
data = [int(x) for x in input().split(' ')]
n, h = data[0], data[1]
maxa = 0
b = [0]*n
for i in range(n):
	data = [int(x) for x in input().split(' ')]
	b[i] = data[1]
	maxa = max(maxa, data[0])
answer = 0
b.sort()
b.reverse()
for bi in b:
	if bi >= maxa:
		h -= bi
		answer += 1
		if h <= 0:
			print(answer)
			exit()
answer += (h + maxa - 1) // maxa
print(answer)

Solution (Python):
import math

N_H = list(map(int, input().split()))

a_b= [list(map(int, input().split())) for _ in range(N_H[0])]
length =len(a_b)

a= [a_b[i][0] for i in range(length)]
b= [a_b[i][1] for i in range(length)]

counter = 0
i = 0
pattern = 0


a_max = max(a)
b_max = max(b)
a_max_idx = a.index(a_max)
b_a_max_idx = b[a_max_idx]

b.pop(a_max_idx)

b.sort()
b.reverse()

    
while True:
    if N_H[1] <= b_max and counter == 0:
        counter += 1
        print(counter)
        break
    
    if N_H[1] <= b_a_max_idx:
        counter += 1
        print(counter)
        break

    if i <= length-2:    
        if b[i] > a_max:
            N_H[1] -= b[i]

            i += 1

            counter += 1

            if N_H[1] <= 0:
                print(counter)
                break
        else:
            counter += math.ceil((N_H[1]-b_a_max_idx)/a_max)+1
            print(counter)
            break
    else:
            counter += math.ceil((N_H[1]-b_a_max_idx)/a_max)+1
            print(counter)
            break

Solution (Python):
from operator import itemgetter

N, H = map(int, raw_input().split())
attackCount = 0

swords = []
for _ in xrange(N):
    swords.append(map(int, raw_input().split()))
swords.sort(key=itemgetter(0), reverse=True)
niceWeapon = swords[0]

subWeapons = [x for x in swords if x[1] > niceWeapon[0]]
subWeapons.sort(key=itemgetter(1), reverse=True)

practicalHP = H

while practicalHP > 0 and subWeapons:
    throwWeapon = subWeapons.pop(0)
    attackCount += 1
    practicalHP -= throwWeapon[1]

if practicalHP > 0:
    attackCount += (practicalHP / niceWeapon[0])
    if practicalHP % niceWeapon[0]:
        attackCount += 1

print attackCount

Solution (Python):
import sys
import math

N, H = map(int, input().split())
D = [list(map(int, input().split())) for i in range(N)]
D = sorted(D, key=lambda x:x[1])
D = D[::-1]
aMax = sorted(D, key=lambda x:x[0])[-1][0]

damage = 0
ans = 0
for d in D:
    if d[1] <= aMax:
        ans += math.ceil((H-damage) / aMax) 
        print(ans)
        sys.exit()
    damage += d[1]
    ans += 1
    if damage >= H:
        print(ans)
        sys.exit()
ans += math.ceil((H-damage) / aMax) 
print(ans)

Solution (Python):
import sys
from math import ceil

def divceil(a,b):
    if a%b > 0:
        return a/b+1
    else:
        return a/b

N, H = [int(x) for x in raw_input().split(" ")]
a, b = [], []
for n in xrange(N):
    _a, _b = [int(x) for x in raw_input().split(" ")]
    a.append(_a)
    b.append(_b)
maxA = max(a)
b = sorted(b, key = lambda x:-x)

damage_sum = 0
for i,_b in enumerate(b):
    if _b > maxA:
        damage_sum += _b
        if damage_sum >= H:
            print i + 1
            sys.exit()
    else:
        i -= 1
        break
print i + 1 + divceil(H-damage_sum, maxA)

Solution (Python):
N, H = map(int, input().split())
maxA, B = 0, 0
rec, recB = [], []

for i in range(N):
    a, b = map(int, input().split())
    rec.append((a, b))
    if a > maxA:
        maxA = a

n = N
for a, b in rec:
    if maxA >= b:
        n -= 1
    else:
        B += b
        recB.append(b)

if H - B <= 0:
    i = 0
    recB = sorted(recB, reverse=True)
    for k in recB:
        H -= k
        i += 1
        if H <= 0:
            print(i)
            break
else:
    ans = max((H - B) // maxA + ((H - B) % maxA != 0), 0)
    print(ans + n)

Solution (Python):
R = lambda type_ = "int": list(map(eval(type_), input().split(' ')))

N, H = R()
a, b = 0, []
while N:
    a_, b_ = R()
    b.append(b_)
    a = max(a, a_)
    N -= 1

b.sort()
i = len(b) - 1
while i >= 0 and H > 0 and b[i] >= a:
    H -= b[i]
    i -= 1
    
if i < 0 and H > 0:
    print(len(b) + (H - 1) // a + 1)
elif H <= 0:
    print(len(b) - i - 1)
elif a > b[i]:
    print(len(b) - i - 1 + (H - 1) // a + 1)

Solution (Python):
from math import ceil
n, h = map(int, input().split())
a = []
b = []
for i in range(n):
    ai, bi = map(int,input().split())
    a.append(ai)
    b.append(bi)
ans = 0
maxa = max(a)
b2 = sorted([i for i in b if i > maxa],reverse=True)
for k in b2:
    if h > 0:
        ans += 1
        h -= k
if h > 0: ans += ceil(h/maxa)
print(ans)

Solution (Python):
import sys,math

N,H = map(int,input().split())
a=[]
b=[]

for i in range(N):
	aa,bb=map(int,input().split())
	a.append(aa)
	b.append(bb)

a.sort(reverse=True)
b.sort(reverse=True)

atk=0
count=0
for i in range(N):
	if b[i]>a[0]:
		atk+=b[i]
		count+=1
		if atk>=H:
			print(count)
			sys.exit()
	else:
		break


count+=math.ceil((H-atk)/a[0])
print(count)

Solution (Python):
import sys

N, H = [int(x) for x in sys.stdin.readline().strip().split()]
AB = [tuple(int(x) for x in sys.stdin.readline().strip().split()) for i in range(N)]
AB.sort(key=lambda x:(-x[0],x[1]))

p = AB[0][0]
qs = [AB[j][1] for j in range(N) if AB[j][1] > p]
qs.sort(key=lambda x:-x)
r = 0
for i in range(len(qs)):
    if H <= 0:
        break
    H -= qs[i]
    r += 1

if H > 0:
    r = r + (H + (p - 1)) // p

print(r)

Solution (Python):
N, monster = map(int,input().split())
sword = [list(map(int,input().split())) for _ in range(N)]
power = 0
attack = 0
sword = sorted(sword, key=lambda x:x[1], reverse=True)

for i in range(N):
    power = max(sword[i][0], power)

for j in range(N):
    if sword[j][1] >= power:
        monster -= sword[j][1]
        attack += 1
        if monster <= 0:
            break
if monster > 0:
    attack += monster // power
    if monster % power != 0:
        attack += 1

print(attack)

Solution (Python):
n, h = (int(s) for s in input().split())

a = []
b = []

for i in range(n):
    a_i, b_i = (int(s) for s in input().split())
    a.append(a_i)
    b.append(b_i)

a_max = max(a)
b.sort(reverse=True)

for i, b_i in enumerate(b):
    if b_i > a_max:
        h -= b_i
        if h <= 0:
            print(i + 1)
            break
    else:
        print(i + (h - 1) // a_max + 1)
        break
else:
    print(len(b) + (h - 1) // a_max + 1)

Solution (Python):
N,H = map(int,input().split())
A = []
B = []
for i in range(N):
    a,b = map(int,input().split())
    A.append(a)
    B.append(b)

import numpy
A = numpy.array(A)
B = numpy.array(B)
AsortA = numpy.sort(A)[::-1]
BsortB = numpy.sort(B)[::-1]

ans = 0
maxattack = AsortA[0]
throw = BsortB[maxattack < BsortB]
if(sum(throw) >= H):
    ak = 0
    for i in range(len(throw)):
        ak += throw[i]
        if(ak >= H):
            ans = i+1
            break
else:
    resH = H - sum(throw)
    ak = int(numpy.ceil(resH/maxattack))
    ans = ak + len(throw)
    
print(ans)

Solution (Python):
import numpy as np

N, H = list(map(int, input().split()))
a = []
b = []
for i in range(N):
    temp0, temp1 = list(map(int, input().split()))
    a.append(temp0)
    b.append(temp1)

b = np.array(b)
b = b[max(a) < b]





if H <= sum(b):
    
    b = np.sort(b)
    for i in range(len(b)):
        H -= b[-1 - i]
        if H <= 0:
            result = i + 1
            break
else:
    if len(b) != 0:
        H -= sum(b)
    dev = int(H / max(a))
    if H % max(a) != 0:
        dev += 1
    result = len(b) + dev

print(result)

Solution (Python):
number_hp = list(map(int, input().split()))
a_b = []

for i in range(number_hp[0]):
    a_b.append(list(map(int, input().split())))
attack_damage_list = []
throw_damage_list = []
for i in range(number_hp[0]):
    attack_damage_list.append(a_b[i][0])
for i in range(number_hp[0]):
    throw_damage_list.append(a_b[i][1])
attack = max(attack_damage_list)
throw_damage_list = [i for i in throw_damage_list if i >= attack]
throw_damage_list.sort(reverse=True)
damage = 0
number = 0
for i in range(len(throw_damage_list)):
    damage = damage + throw_damage_list[i]
    number = number + 1
    if damage >= number_hp[1]:
        break
if damage >= number_hp[1]:
    pass
else:
    attack_number = int((number_hp[1] - damage) // attack)
    number = number + attack_number
    if int((number_hp[1] - damage) % attack) != 0:
        number = number + 1
print(number)