SCPC 후기.

알고스팟/알고리즘 2015.10.31 00:34


일단 일차 예선은 무난히 통과했다.


대회 중에 4번 문제를 푸는데 잼있었는데 

1) 두 점간의 거리가 희한하게 정의되고 (일반 euclidean distance가 아님. 이름 까먹음.. 실제 정의는 공유하면 안될 것 같음.)

2) 한점과 선분의 거리또한 희한하게 정의될 때

3) maximal distance를 minimize하는 점을 찾아라. 라는 문제였는데


일단  선분이 아니라 점의 집합이 주어졌으면 쉽게 풀리는 문제였다. (힌트, 최대, 최소값의 관점에서 생각해보기) 

다만, 어떤 선분의 끝점이 optimal P와의 거리에 이용될 지 미리 모르기 때문에..처음에는 2^n개의 끝점 부분집합을 다 시도해보는 방식으로 했는데 TLE.. 좌절하고 다시 생각해보니 n개의 선분이 주어지면 n+1개의 in between point만 고려하면 된다. 그러면 어떤 끝점이 이용될지는 자동으로 정해지니깐!


이게 신선한 깨닳음 이었다. 2차도 잼있는 문제가 많길!

설정

트랙백

댓글

Quora에 쓴글. 동전을 100만번 던졌을 때, 최소 한번 이상 10번의 연속된 앞면을 볼 확률.

알고스팟/알고리즘 2015.05.14 05:00


요세 블로그 보다 외국판 지식인인 Quora 하는 재미에 푹 빠졌다. 네이버 지식인 따위와 비교할 수 없는 양질의 질문과 답변, 유명인들도 상주하며 실시간으로 대답해주고, 기계학습 알고리즘 등이 적용 되 자동으로 추천되는 질문/답변들이 굉장히 읽을만 하다. 아직 쪼랩이라 답변은 많이 못달고 있지만. 간단한 확률 문제들을 하나씩 달아주는 재미에 하고있다. 이번 포스트는 내 Quora글을 그대로 배껴서 그냥 옮겨본다. 


http://www.quora.com/If-I-flip-a-fair-coin-1-million-times-how-do-I-calculate-the-probability-of-there-being-at-least-1-series-of-10-heads-in-a-row/answer/Nate-Namgun-Kim?__snids__=1150148690&__nsrc__=2



Quora 질문은 동전을 1만개 던졌을 때, 최소 한번 이상의 10번 연속된 앞면을 볼 확률이다. 


내 답변 : 


First off, I'm interpreting your question as "what is the probability that, at least once, you flip at least 10 heads in a row". Let's think about it step by step.


1) Bad idea: generate all possible permutations of 1 million coin tosses, count which ones contain our pattern. Straightforward but little thought involved. And since, 2^1000000 is too big of a number to generate all, this approach won't fly.

2) Consider a simple trick: instead of directly computing the answer, compute "the probability that our permutation consists only of parts of 9 consecutive heads or less." Let's denote 

an = the number of ways to flip n coins such that at no point do you flip more than 10 consecutive heads. then the answer to your question is 

1 - (a1000000/21000000).

3) Key insight: think about the last 10 rolls of a_n and look for any patterns. 

an must have its last 10 rolls in one of the following ways:
an ends in 
T
TH
THH
THHH
THHHH
THHHHH
.
..
THHHHHHHH
THHHHHHHHH

If you delete this last part of the sequence, you get the following recurrence relation. 
an+10 =an+9 + an+8 + ... + an+1 + an, with initial conditions 
ak = 2k, 0 <= k <= 9. 

 
Now simply, iteratively compute an up to a million to answer your original question, using any programming language of your choice. In python I did the work for you (see code here 

ideone.com

Ideone.com) and as you guessed, with a million tosses, the answer trivially approaches 99.9%.  with fewer rolls, see below

With 100 rolls, 4.41%
with 1000 rolls, 38.5%
with 10000 rolls 99.25%. 

On a side note, by linearity of expectation, you can compute that on average you are expected to see about 976 such consecutive 10 heads in a million tosses.

Also, there is a whole field of mathematics called linear recurrences and generating functions that aim to solve questions of this sort and their approximation techniques. Our simple question happened to be a more general version of the famous fibonacci sequence. Anyways, hope my answer helped and comment if you have any questions :D



설정

트랙백

댓글

1) 신기한 통계 문제 몇개. Names In the Boxes, Marriage Problem

알고스팟/알고리즘 2015.05.12 15:55


아직 인턴 시작전이라 나른한 오후 시간대에 최근에 접해본 신기한 통계 문제 두개를 정리해본다. 첫번째 문제는 Names In the Boxes로 검색하면 여러가지 변형 문제들을 접할 수 있는데 그 중 내가본 버전을 각색하면 다음과 같다.


내일 사형 집행을 앞둔 서로 다른 이름을 가진 흉악한 죄수 100명이 있다. 죄는 미워하되 죄인은 미워하지 말라고 누가 그랬던가, 교도소장을 지내는 당신은 이들에게 기회를 주고자 한다. 


"당신들에게 기회를 주겠소. 100개의 구별할 수 없는 상자에 개개인의 서로다른 죄수 이름을 무작위로 넣고 어떤 밀실에 일렬로 진열 해놓겠소. 이제 100명이 모두 한명씩 차례차례 밀실에 들어가 50번의 기회 중에 자신의 이름이 담긴 상자를 찾는데 성공한다면 사형을

면해 주겠소. 서로 사전에 어떤 모의를 하든 좋소. 하지만 밀실을 나온자는 아직 밀실에 들어간 자에게 아무런 힌트를 줄수 없소"



간단히 생각하면 100의 죄수 전체의 성공 확률은 개개인의 성공확률 1/2의 100승과 동일하다. 서로 사전에 어떤 모의를 하던간에 추가 정보를 서로에게 제공 할 수 없으므로 이 확률 게임의 상한은 



일 것 같다.


근데 놀라운 사실은 이게임의 성공 확률 하한을 30% 이상 보장해주는 전략이 있다는 사실이다. naive approach와 비교해서 어마어마한 improvement가 아닐 수 없다. 이 전략의 통찰력은 100명의 서로다른 원소를 가진 순열이 있을 때, 이 순열의 사이클의 길이는 50이하일 가능성이 많다는 것이다. 무슨 말인지 아리까리하니, "순열의 사이클"이란 개념부터 설명이 필요하다. 아래와 같은 순열로 예를 들어본다.



위와 같은 순열 (0-indexed) 은 이렇게 해석 할 수 있다. 0번 박스를 열어 나온 숫자인 1번박스를 연다. 1번박스를 열어 나온 숫자가 2이니. 2번박스를 연다.... 5번박스를 열어 나온 숫자가 0번인데 0번 박스는 이미 우리가 처음 시작한 박스이다. 이 경우 길이 6의 사이클을 가진다고 말한다.


위 통찰력을 이용하면 죄수들은 다음과 같은 전략을 사용할 수 있다. 박스를 열기전 사전에 모의를 통해 각 죄수들에게 번호를 부여한다. 이제 모든 죄수들은 어떤 죄수가 몇번인지 죽을 힘을 다해 달달 외운다. 이제 각 죄수가 밀실에 들어가 다음과 같은 순서로 박스를 열어 나간다. 먼저 자신의 번호를 가진 박스를 연다. 그 박스를 열어 나온 사람의 이름에 해당하는 박스를 다음에 연다. 이 과정을 50번의 기회 모두 반복한다. 


위와 같은 전략을 모두 죄수가 사용 할 시 성공조건은 다음과 같다. 박스의 배치 순열이 50 이하의 사이클로 이루어져 있다면, 모든 죄수는 자기 번호 박스를 열고 거기서 나온 번호를 따라 순차적으로 박스를 여는 전략으로 반드시 주어진 50번의 기회 안에 자기 이름을 찾을 수 있다! 왜냐하면 모든 박스가 속한 사이클의 길이가 50이하이기 때문이다!


그럼 위 전략의 성공 확률은 박스의 순열이 길이가 50이하인 사이클로만 이루어진 경우의 확률과 동치이다. 이 확률이 바로 30%정도이다.


이 확률을 구해보자. 먼저 

2n개의 원소를 가진 순열에서 k > n 길이의 사이클이 존재하는 순열의 수를 a_k라 정의하자.


그럼 먼저 이 사이클이 어떤 k개의 원소를 포함 하는지를 정하자. 이는 당연히 

이다. 이 k개의 원소들이 cycle즉 원순열을 이루므로 이 원순열의 개수는 

 이다. 이제 나머지 2n-k 개의 원소들이 아무렇게나 배치되면 된다. 이는 

 이다. 

종합하면,


이다. 


따라서, 우리가 원하는 성공 확률 P_S는 전체 모든 순열의 경우 (2n)! 에서 a_k가 n+1인 경우부터 2n까지를 하나하나 다 빼주면 된다. 식으로 표현하면 



P(success)의 극한값이 무려 30.7%이다. n = 100인 경우에 대해서는 31프로나 된다. 신기하지 않을 수가 없다.


아무튼 이 문제로 알수 있는 사실은 어떤 순열의 사이클의 분포만으로도 brute-force 할 수 밖에 없는 문제에 엣지를 가질 수 있다는 사실이다. 물론 실생활에 적용할 여지는 별로 없다. 이 사실을 알더라도 로또 당첨 혹은 알려진 확률 게임에 대한 어떠한 엣지도 얻을 수 없다. 그래도 그냥 이런 사실이 있다는 걸 아는건 신선한 경험이라고 생각한다.






설정

트랙백

댓글

GCJ 2015 Round 1C. Battleship, Typewriter Monkey, Less Money More Problems

알고스팟/알고리즘 2015.05.11 14:22

1) Battleship


문제 해설 - 두 플레이어, 형과 동생이 게임을 한다. 게임은 다음과 같다. R x C 보드가 주어 졌을 때, 동생이 1 x W 배틀쉽을 보드에 평행하게 어느 한 곳에 위치시킨다. 형은 눈을 가린 상태에서 R x C보드의 각 칸(i, j)를 추측해서 배틀쉽을 찾아야 한다. 이러면 너무 쉬운 문제이다. 문제의 catch는, 동생은 지금까지 형이 말한 추측시도와 일관성이 깨지지 않는 선에서 형 몰래 배틀쉽의 위치를 조정 할 수 있다. 형과 동생이 모두 optimal하게 게임을 플레이한다고 가정할 때, 형은 최대 몇 번의 추측이 필요할까?


게임 이해를 돕기 위해 R, C, W가 각각 1, 4, 2라고 가정해보자. 여기서 형의 optimal 전략중 하나는 다음과 같다. 먼저 (1,2)에 배틀쉽이 있는지 묻는다. 그에 대한 답이 YES라면, 배틀쉽의 나머지 부분은 (1,1)이나 (1,3)에 위치 할 수 밖에 없다. 근데 (1,1)을 다음 guess로 물어본다면 동생은 optimal하게 게임을 하기 때문에 배틀쉽을 (1,3)으로 옮긴 뒤 "NO"라고 한번 꼼수를 부릴 수있다. 그렇게 하더라도, 형은 (1,3)을 다시 guess한다면 게임은 끝난다. 왜냐하면 더 이상 이 전의 대답들과 일관성을 유지하는 범위 내에서 배틀쉽을 옮길 자리가 없기 때문이다.


여기서 형의 optimal 플레이에 대한 동생의 optimal 전략을 생각해 볼 수 있다. 일단 동생은 배틀쉽을 각 R행마다 옮길 수 있기 때문에 형은 최소한 R행에 대해 일일히 process of elimination을 통해 확인 해야 한다. 또한 각 R행 안에는 C/W만큼 배틀쉽이 위치 할 수 있는 자리가 있다. 배틀쉽이 위치한 블록을 찾는건 R*C/W - 1만큼의 시도안에 찾을 수 있다. 이제 배틀쉽의 길이인 W만큼 말해야 되는데.. 여기서도 동생은 1번의 거짓말을 시도할 수 있다. 하지만 생각해보면, 이건 C/W의 나머지가 1 이상인 경우 만 해당이 된다. 이 직관은 그림을 그려서 생각해보면 자명하다. 요약하면.. 


def solveRevised(R, C, W):
    rem = C%W
    if rem != 0:
        rem = 1
    return ((C/W)*R) - 1 + W + rem

    

1) Typewriter Monkey


이 문제 small 인풋을 대회 할 때는 제일 먼저 풀었다. 문제는 이해하기 쉽다.

작가인 당신은 타자치기가 귀찮아 원숭이를 대신 고용해 타자를 치게 하고 싶다. 하지만 원숭이는 무뇌해서 어떤 K개의 키를가진 키보드 keyboard가 주어졌을 때 K개의 키에대해 uniformly random 하게 (즉 아무거나 랜덤하게 편향 없이 하나 골라서) 타이핑 한다.


문제에서는, 원숭이가 K개의 키보드를 가지고 S번 타이핑 한다. 그럼 원숭이가 입력할 수 있는 경우의 수는 총 K^가 된다. 각각의 경우의 수가 우리가 원하는 패턴 L을 포함 할 시 1개의 바나나를 원숭이에게 지급한다. 예를들어 원숭이가 abcabc를 쳤는데 L = abc일 경우, 원숭이에게 2개의 바나나를 지급한다. 문제에서는, 원숭이에게 평균적으로 지급해야 할 바나나의 기대값 E을 찾고, 또한 원숭이에게 최악의 경우에 지급 해야 할 가장 많은 바바나의 수 W를 구해서 W-E를 반환해야 한다. 


small input은 정말 아무런 생각 없이 K^S개의 모든 경우의 수를 만들어 나열한 뒤 각각의 입력에 대해 L이 몇번 포함 되는지 찾고 이를 다 더해서 기대값 E를 구한 뒤, 그중 가장큰 값 W를 찾아 놨다가 W-E를 반환하면 된다. 근데 large input에 대해 K와 S모두 100까지 가능하다. 이 경우.. 100^100의 경우의 수는 절대 모두 나열 못할 만큼 크다.


해법은, KMP를 변형해서 DP로 푸는 방법과 기대값의 선형성을 이용해서 푸는 방법이 있다.

기대값의 선형성은 algospot 혹은 감히 한국의 PS신(..) Nana^님께서 알려주신 방법이다.


먼저 기대값 부분을 생각해보면 다음과 같다.


1번은 위에 설명한 제일 무식한 방법이고..2번도 비슷하게 무식하다. 다만 접근을 0개의 바나나를 포함할 경우, 1개의 바나나를 포함할 경우, 2개의 바나나를 포함할 경우, ..., S-L개를 포함할 경우. 이렇게 센다. 근데 생각해보면 이건 중복된 경우를 제외해서 똑바로 세기가 무척 어렵다. 왜냐하면 문제의 조건이 overlapping matching pattern도 독립하게 세기 때문이다. 어마어마한 통찰력을 가지고 있다면 위 방법 말고 다음과 같이 구할 수 있다.





기대값의 선형성이라는 개념을 사용한다. 설명을 덧 붙이자면, 바나나가 있을 모든 경우는 다음과 같이 쪼갤 수 있다. 그바나나의 시작 위치가 0인경우, 1인경우, 2인경우 ,..., S-L인 경우. 예를들어 K = abcdefg고 S = 6, L = abc라면, 다음과 같이 쪼개진다.


abc???

?abc??

??abc?

???abc


얘내는 서로 다다르지만 발생확률이 1/7*1/7*1/7로 모두 동일하다. 또한 각각의 경우, 뒤에 혹은 앞에 어떤 키가 오든지 하나의 바나나로만 간주한다. (**이게 리얼 키다..) 얘를들어 몽키가 abcabc를 쳤다고 하자 그럼 얘는 abc???에 의해 한번 카운트되고 ???abc에 의해 또 한번 카운트 된다. 그렇기 때문에 발생확률을 그냥 다 곱해서 더하는

E = 4*(1/7)^3가 기대값 이다.


확장하면 

E = (S-L + 1) * prob(L)이다. 존나 깔끔 하다..jizzed.

이게 기대값이고 최악의 경우는 greedy하게 0번에서부터 매치시켜 나가면 된다.


    
def solveLarge(Keyboard, Pattern, S):
    K = len(Keyboard)
    L = len(Pattern)
    
    expected = 1.0
    possible = 1
    for i in range(0, L):
        cnt = 0
        for j in range(0, K):
            if (Pattern[i] == Keyboard[j]): cnt += 1
        expected *= 1.0 * cnt / K
        if not cnt: possible = 0
        
    expected *= (S - L + 1) 
    mmax = 0
    #greedily find the max. first see if Pattern repeats itself.
    if possible:
        my_step = L
        for step in range(1, L):
            ok = 1
            for i in range(step, L):
                if Pattern[i] != Pattern[i - step]: ok = 0
            if ok:
                my_step = step
                break
        for i in range(L-1, S, my_step):
            mmax += 1
    return mmax - expected      
#f = open("A-small-attempt0.in", 'r')
f = open("B-large-practice.in", 'r')
f2 = open("outputBananaSmall.txt", 'w') 
t = int(f.readline())
for i in xrange(t):
    s = "Case #" + str(i+1) + ": "
    
    l = f.readline().strip().split()
    S = int(l[2])
    K = f.readline().strip()
    L = f.readline().strip()
    print K, L, S
    if i == t-1:
        f2.write(s+str(solveLarge(K, L, S)))
    else:
        f2.write(s+str(solveLarge(K,L,S))+'\n')

f.close()
f2.close()


3번. Less Money, More Problems.


이 문제는 다음과 같다. 현재 PS나라에 사용 중 인 통화단위의 집합 D가 있다. (우리나라 기준으로 D = [10원, 50원, 100원, 500원, 천원, 5천원, 만원, 5만원] 이다.) 근데 하루는 한 납세자가 어마어마하게 큰돈을 10원짜리로 모두 납세했다. 이에 빡친 한은총재가 다음과 같이 공포한다. "납세 할 때 각 통화는 최대 C번만 사용 할 수 있고 그 이상은 안받음!" 


이에 당연히 많은 문제가 생긴다. 어떤 금액은 아예 납부가 불가능 할 수도 있다. 혹은 어떤 금액 V 이상은 아예 납부가 불가능하다. (납부액의 상한) 이에 한은 경제통화국 부장인 당신은 기존의 통화단위 집합 D에 최소한의 새로운 통화단위만 추가해 어떤 상한 금액 V까지는 모두 납세 가능하도록 하고 싶다. PS 고수인 당신이 한은 경제통화국 부장을 도와주자!


이 문제 large 파일의 상한은 

1 ≤ C ≤ 100.
1 ≤ D ≤ 100.
1 ≤ V ≤ 109.

와 같다. https://algospot.com/judge/problem/read/CONCERT 나 DP packing 문제가 비슷한 맥락이다. 하지만 이 문제의 C, D, V조건 때문에 DP로 모든 가능한 금액을 다 만들어보고 새로운 통화를 추가하는 건 시간안에 못 풀 가능성이 높다. 

따라서, 이 문제는 greedy하게 풀어야 한다.
간단한 증명을 통해 어떻게 해결 해야 할 지 생각해보자.

 현재까지 통화단위 어떤 집합 D를 사용하여 [1, x] 범위까지는 모두 납세 할 수 있다고 하자. x가 V이상이라면 더 이상 새 통화를 추가 할 필요없이 끝난다. V 이하라면 어떤 통화를 추가해야 할까? 정답은, x+1을 추가해야 한다. 왜냐하면 x+2 이상의 통화단위를 추가 한다면 x+1은 커버가 불가능하다. 또한, x이하의 통화 y를 추가하면 y*C + x까지는 (x까지는 커버가 되니 그 이상은 y를 한번, 두번, ..., C번 사용하면서 확장해 나갈 수 있다.) 커버가 되지만 이 범위는 (x+1)*C + x보다는 작은 범위이다. 따라서 x+1을 추가하는게 optimal 하다. 이렇게 x가 V이상이 될 때 까지 greedy하게 통화를 추가해주면 된다.
def solveLarge(my_set, V, C):
    my_set.append(99999999999999)
    last_cover = 0
    res = 0
    for each in my_set:
        while last_cover + 1 < each:
            if last_cover >= V: break
            coin = last_cover + 1
            res += 1
            last_cover += coin * C
        last_cover += each*C
    return res
    
f = open("C-large-practice.in", 'r')
#f = open("test.txt", 'r')
f2 = open("outputMoneyLarge.txt", 'w')  
t = int(f.readline())
for i in xrange(t):
    s = "Case #" + str(i+1) + ": "
    
    l = f.readline().strip().split()
    v = int(l[2])
    c = int(l[0])
    l = f.readline().strip().split()
    l = map(int, l)
    ans = solveLarge(l, v, c)
    #print l, v,
    ##print '-----------'
    if i == t-1:
        f2.write(s+str(ans))
    else:
        f2.write(s+str(ans)+'\n')

f.close()
f2.close()


설정

트랙백

댓글

2015 GCJ Round 1B Counting culture.

알고스팟/알고리즘 2015.05.04 16:26


1. Counting Culture.


small input은 DP로 풀 수 있다. 다음의 점화식을 이용한다.



스몰인풋은 n이 10^6승 미만 이므로, 10^6승까지 미리 pre-compute을 해놓고 각 테스트 케이스에 대하여 캐쉬값을 반환하면 된다.


large input은 10^14승이라. 32비트 정수배열을 잡는다해도 400테라바이트다. Greedy한 접근을 요함을 알 수 있다.


그리디 접근의 핵심은 다음과 같다. 주어진 n이 d자리수 일 때, 생각해보면 뒤집기 연산을 통해서 d-1자리수에서 d자리수로 커질 수 없기 때문에, 항상 1자리 -> 10자리 -> 100자리 -> 1000자리 -> 10000자리 -> ... -> d자리까지 최적으로 도달해야 한다. 이건 생각해보면 현재 d-1자리의 10...0라 가정할 때 99....9로 최대한 빨리 도달한 다음 +1을 해주면 된다.


근데 어떻게 해야 10...0에서 99....9로 최적으로 도달할까? 예를들어보자,


100000에서 999999으로 최적으로 도달하고 싶다. 그럼 일단 제일 먼저 100000에서 100009로 증가한 뒤 뒤집어서 900001로 간 뒤 999999까지 도달하는 방법이 있다. 왜? 100002일 때 뒤집지 않는가? 이건 손으로 계산해보면 2에서 9까지는 7번만 추가하면 되지만, 200001에서 900001이상으로 가려면 최소 7번 이상이 필요하기 때문이다. 

다음과 같이 걸린다. 

200001 -> 200009 -> 900002. 여기서 이미 8+1 = 9번이 걸림을 알 수 있다.


이걸 좀 더 확장해 생각해보면, 100009에서 뒤집는게 10000x (1<= x <=8)보다 최적이고,

100099에서 뒤집는게 1000xy (1<= x<= 9, 1<= y <=8)에서 뒤집는것 보다 낫다. 이걸 

100009, 100099, ..., 109999, 199999까지 다 해본 뒤 그 중에 가장 최적의 답을 구하는 주는 답을 택한다. 



예를 들면, 

1000에서 9999까지 제일 빨리 가려면, 1000 -> 1099 -> 9901 -> 9999로, 99+1+98 = 198번이 걸린다.


그럼 이제 d자리수인 n의 답을 구하려면, 

1 -> 10 -> 100 -> ... d 디짓까지 도달하는 횟수를 다 더한 뒤, 10....0 (d-1개) 에서 n까지 걸리는 도달 횟수를 더해서 반환하면 된다.





def minsteps(start,goal):
    if start == goal: return 0

    best = int(goal) - int(start)
    C = len(start)
    for cif in range(C):
        suffix = goal[::-1]
        intermediate = start[:C-cif] + suffix[C-cif:]
        
        if intermediate[::-1] > goal: continue
        candSum = int(intermediate) - int(start) + 1
        candSum += int(goal) - int(intermediate[::-1])
        if candSum < best:
            best = candSum
      
    return best

def solve(goal):
    start = '1'
    answer = 1
    #quickly get upto 'd' digits = len(goal).
    while len(start) < len(goal):
        #sum up the steps needed to get from '100..0' to '999...9'
        answer += minsteps(start, '9'*len(start)) + 1 
        #go to one more digit
        start += '0'
        
    answer += minsteps(start,goal)
    return answer

cache = [-1]*1000001
def solve_DP(n):
    
    for i in xrange(11, n+1):
        if i % 10 != 0 and rev(i) < i:
            cache[i] = 1 + min(cache[rev(i)], cache[i-1])
        else:
            cache[i] = 1 + cache[i-1]
#   print n, cache[n]
    return cache[n] 

f = open("A-large-attempt0.in", 'r')
f2 = open("outputCountingLarge.txt", 'w')   
t = int(f.readline())
for i in xrange(t):
    s = "Case #" + str(i+1) + ": "
    
    n = f.readline().rstrip()
    if n != '1':
        ans = solve(n)
        tryMe = str(int(n) - 1)
        ans = min(ans, 1+solve(tryMe))
    else:
        ans = solve(n)
    if i == t-1:
        f2.write(s+str(ans))
    else:
        f2.write(s+str(ans)+'\n')

f.close()
f2.close()


설정

트랙백

댓글