Problem:
Score : 300 points

Problem Statement

Takahashi is standing on a multiplication table with infinitely many rows and columns.

The square (i,j) contains the integer i \times j. Initially, Takahashi is standing at (1,1).

In one move, he can move from (i,j) to either (i+1,j) or (i,j+1).

Given an integer N, find the minimum number of moves needed to reach a square that contains N.

Constraints

2 \leq N \leq 10^{12}

N is an integer.

Input

Input is given from Standard Input in the following format:

N

Output

Print the minimum number of moves needed to reach a square that contains the integer N.

Sample Input 1

10

Sample Output 1

5

(2,5) can be reached in five moves. We cannot reach a square that contains 10 in less than five moves.

Sample Input 2

50

Sample Output 2

13

(5, 10) can be reached in 13 moves.

Sample Input 3

10000000019

Sample Output 3

10000000018

Both input and output may be enormous.

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define abs(a) (a) < 0 ? (-(a)) : (a)

typedef struct LinkedList {
    long val;
    struct LinkedList *next;
} LinkedList;

LinkedList* create_list(long val) {
    LinkedList *list = malloc(sizeof(LinkedList));
    list->val = val;
    list->next = NULL;
    return list;
}
LinkedList *append(LinkedList *list, long val) {
    if (list == NULL) {
        list = create_list(val);
        return list;
    }

    LinkedList *init = list;
    while(list->next != NULL) {
        list = list->next;
    }
    list->next = create_list(val);
    return init;
}

int is_sosu(long k) {
    if (k < 2)
        return 0;
    else if (k == 2)
        return 1;
    else if (k % 2 == 0)
        return 0;
    double sqrtNum = sqrt(k);
    for (long i = 3; i <= sqrtNum; i += 2)
    {
        if (k % i ==0)
            return 0;
    }
    return 1;
}

LinkedList* soinsu(long k, LinkedList* list) {
    if (k < 2) {
        return list;
    } else if (k == 2) {
        list = append(list, 2);
        return list;
    } else if (k % 2 == 0) {
        list = append(list, 2);
        list = soinsu(k / 2, list);
        return list;
    }

    double sqrtNum = sqrt(k);
    for (long i = 3; i <= sqrtNum; i += 2) {
        if (k % i == 0)
        {
            list = append(list, i);
            list = soinsu(k / i, list);
            return list;
        }
    }
    list = append(list, k);
    return list;
}

int main () {
    long N;
    scanf("%ld", &N);

    LinkedList *list = soinsu(N, NULL);
    long length = 0;
    LinkedList *init = list;
    while(list != NULL) {
        //printf("%ld, ", list->val);
        list = list->next;
        length++;
    }
    long *soinsu_list = malloc(length * sizeof(long));
    list = init;
    long i = 0;
    while(list != NULL) {
        soinsu_list[i++] = list->val;
        list = list->next;
    }

    //printf("\n");
    //printf("count: %d\n", length);
    long min = N + 1;
    long min_a = 1;
    long min_b = 1;
    for (long i = 0; i < 1 << length; i++) {
        long a = 1;
        long b = 1;
        for (int j = 0; j < length; j++) {
            if (i & (1 << j)) {
                a *= soinsu_list[j];
            } else {
                b *= soinsu_list[j];
            }
        }
        //printf("%ld * %ld\n", a, b);
        if (abs(a - b) < min) {
            min = abs(a - b);
            min_a = a;
            min_b = b;
        }
    }
    printf("%ld\n", min_a - 1 + min_b - 1);

    return 0;
}