Very Suspicious (Codeforces 1670D)
Tags: Greedy, geometry

Sehr Sus is an infinite hexagonal grid as pictured below, controlled by MennaFadali, ZerooCool and Hosssam.They love equilateral triangles and want to create $$$n$$$ equilateral triangles on the grid by adding some straight lines. The triangles must all be empty from the inside (in other words, no straight line or hexagon edge should pass through any of the triangles).You are allowed to add straight lines parallel to the edges of the hexagons. Given $$$n$$$, what is the minimum number of lines you need to add to create at least $$$n$$$ equilateral triangles as described?  Adding two red lines results in two new yellow equilateral triangles. 

Input: The first line contains a single integer $$$t$$$ ($$$1 \le t \le 10^5$$$) — the number of test cases. Then $$$t$$$ test cases follow.Each test case contains a single integer $$$n$$$ ($$$1 \le n \le 10^{9}$$$) — the required number of equilateral triangles.

Output: For each test case, print the minimum number of lines needed to have $$$n$$$ or more equilateral triangles.

Note: In the first and second test cases only 2 lines are needed. After adding the first line, no equilateral triangles will be created no matter where it is added. But after adding the second line, two more triangles will be created at once.   In the third test case, the minimum needed is 3 lines as shown below.  

Sample Inputs:
4
1
2
3
4567

Sample Outputs:
2
2
3
83

Solution (Python):
import sys, math
input = sys.stdin.readline
for _ in range(int(input())):
    print(math.ceil(math.sqrt(3 / 2 * int(input()))))

Solution (Python):
import sys
input = sys.stdin.readline
from bisect import bisect_left

def f(a, b, c):
    (a, b, c) = sorted((a, b, c))
    return (b, a + 1, c, 2 * (b + c))
(a, b, c) = (0, 0, 0)
dp = []
while not dp or dp[-1] < 1000000000.0:
    (a, b, c, v) = f(a, b, c)
    if not dp:
        dp.append(v)
    else:
        dp.append(dp[-1] + v)
for _ in range(int(input())):
    n = int(input())
    ans = bisect_left(dp, n)
    print(ans + 1)

Solution (Python):
import sys
input = sys.stdin.readline
import math

def solve():
    n = int(input())
    if n <= 6:
        return 2 if n <= 2 else 3
    k = int(math.sqrt(n // 6))
    while 6 * (k + 1) ** 2 < n:
        k += 1
    v = 6 * k ** 2
    if v >= n:
        return 3 * k
    v += 4 * k
    if v >= n:
        return 3 * k + 1
    v += 4 * k + 2
    if v >= n:
        return 3 * k + 2
    return 3 * k + 3
for _ in range(int(input())):
    print(solve())