Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10 ** 5)

N, Z, W = map(int, input().split())
a = list(map(int, input().split()))
a.reverse()
a += [W] #最後にYさんの手札を加えておく
dp_T = [-1] * (N + 1) #Xの手番
dp_F = [-1] * (N + 1) #Yの手番

def calc(n, flag): #n: 残りの山の枚数　flag: ターンの管理
    #既に計算済みの場合その値を返す
    # if flag == True and dp_T[n] != -1:
    #     return dp_T[n]
    # if flag == False and dp_F[n] != -1:
    #     return dp_F[n]

    if n == 1: #山の残り枚数が1枚の時 -->引くしかなく得点が決定
        return abs(a[0] - a[n])
    if flag == True: #Xのターン-->大きくしたい
        tmp = 0
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n: #残り枚数0で相手に渡す = 自分が最後の1枚を引く -->相手の手札が決まっているから得点が決定
                tmp = max(tmp, abs(a[0]-a[n]))
            else: #残り枚数が1枚以上ある時、手番は相手に変える
                tmp = max(tmp, calc(n-i, not flag))
        dp_T[n] = tmp
        return tmp
    if flag == False: #Yのターン-->小さくしたい
        tmp = 10 ** 10 #最大値
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n - 1: #残り0枚で相手に渡す
                tmp = min(tmp, abs(a[0] - a[n]))
            else:
                tmp = min(tmp, calc(n-i, not flag))
        dp_F[n] = tmp
        return tmp

print (calc(N, True))


Fixed submission:
import sys
sys.setrecursionlimit(10 ** 5)

N, Z, W = map(int, input().split())
a = list(map(int, input().split()))
a.reverse()
a += [W] #最後にYさんの手札を加えておく
dp_T = [-1] * (N + 1) #Xの手番
dp_F = [-1] * (N + 1) #Yの手番

def calc(n, flag): #n: 残りの山の枚数　flag: ターンの管理
    #既に計算済みの場合その値を返す
    if flag == True and dp_T[n] != -1:
        return dp_T[n]
    if flag == False and dp_F[n] != -1:
        return dp_F[n]

    if n == 1: #山の残り枚数が1枚の時 -->引くしかなく得点が決定
        return abs(a[0] - a[n])
    if flag == True: #Xのターン-->大きくしたい
        tmp = 0
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n: #残り枚数0で相手に渡す = 自分が最後の1枚を引く -->相手の手札が決まっているから得点が決定
                tmp = max(tmp, abs(a[0]-a[n]))
            else: #残り枚数が1枚以上ある時、手番は相手に変える
                tmp = max(tmp, calc(n-i, not flag))
        dp_T[n] = tmp
        return tmp
    if flag == False: #Yのターン-->小さくしたい
        tmp = 10 ** 10 #最大値
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n - 1: #残り0枚で相手に渡す
                tmp = min(tmp, abs(a[0] - a[n]))
            else:
                tmp = min(tmp, calc(n-i, not flag))
        dp_F[n] = tmp
        return tmp

print (calc(N, True))

Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10 ** 5)

N, Z, W = map(int, input().split())
a = list(map(int, input().split()))
a.reverse()
a += [W] #最後にYさんの手札を加えておく
dp_T = [-1] * (N + 1) #Xの手番
dp_F = [-1] * (N + 1) #Yの手番

def calc(n, flag): #n: 残りの山の枚数　flag: ターンの管理
    #既に計算済みの場合その値を返す
    # if flag == True and dp_T[n] != -1:
    #     return dp_T[n]
    # if flag == False and dp_F[n] != -1:
    #     return dp_F[n]

    if n == 1: #山の残り枚数が1枚の時 -->引くしかなく得点が決定
        return abs(a[0] - a[n])
    if flag == True: #Xのターン-->大きくしたい
        tmp = 0
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n: #残り枚数0で相手に渡す = 自分が最後の1枚を引く -->相手の手札が決まっているから得点が決定
                tmp = max(tmp, abs(a[0]-a[n]))
            else: #残り枚数が1枚以上ある時、手番は相手に変える
                tmp = max(tmp, calc(n-i, not flag))
        dp_T[n] = tmp
        return tmp
    if flag == False: #Yのターン-->小さくしたい
        tmp = 10 ** 10 #最大値
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n - 1: #残り0枚で相手に渡す
                tmp = min(tmp, abs(a[0] - a[n]))
            else:
                tmp = min(tmp, calc(n-i, not flag))
        dp_F[n] = tmp
        return tmp

print (calc(N, True))


Fixed submission:
import sys
sys.setrecursionlimit(10 ** 5)

N, Z, W = map(int, input().split())
a = list(map(int, input().split()))
a.reverse()
a += [W] #最後にYさんの手札を加えておく
dp_T = [-1] * (N + 1) #Xの手番
dp_F = [-1] * (N + 1) #Yの手番

def calc(n, flag): #n: 残りの山の枚数　flag: ターンの管理
    #既に計算済みの場合その値を返す
    if flag == True and dp_T[n] != -1:
        return dp_T[n]
    if flag == False and dp_F[n] != -1:
        return dp_F[n]

    if n == 1: #山の残り枚数が1枚の時 -->引くしかなく得点が決定
        return abs(a[0] - a[n])
    if flag == True: #Xのターン-->大きくしたい
        tmp = 0
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n: #残り枚数0で相手に渡す = 自分が最後の1枚を引く -->相手の手札が決まっているから得点が決定
                tmp = max(tmp, abs(a[0]-a[n]))
            else: #残り枚数が1枚以上ある時、手番は相手に変える
                tmp = max(tmp, calc(n-i, not flag))
        dp_T[n] = tmp
        return tmp
    if flag == False: #Yのターン-->小さくしたい
        tmp = 10 ** 10 #最大値
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n - 1: #残り0枚で相手に渡す
                tmp = min(tmp, abs(a[0] - a[n]))
            else:
                tmp = min(tmp, calc(n-i, not flag))
        dp_F[n] = tmp
        return tmp

print (calc(N, True))

Buggy python submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(2000)

N, Z, W = map(int, input().split())
a = list(map(int, input().split()))
a.reverse()
a += [W] #最後にYさんの手札を加えておく
dp_T = [-1] * (N + 1) #Xの手番
dp_F = [-1] * (N + 1) #Yの手番

def calc(n, flag): #n: 残りの山の枚数　flag: ターンの管理
    #既に計算済みの場合その値を返す
    if flag == True and dp_T[n] != -1:
        return dp_T[n]
    if flag == False and dp_F[n] != -1:
        return dp_F[n]

    if n == 1: #山の残り枚数が1枚の時 -->引くしかなく得点が決定
        return abs(a[0] - a[n])
    if flag == True: #Xのターン-->大きくしたい
        tmp = 0
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n: #残り枚数0で相手に渡す = 自分が最後の1枚を引く -->相手の手札が決まっているから得点が決定
                tmp = max(tmp, abs(a[0]-a[n]))
            else: #残り枚数が1枚以上ある時、手番は相手に変える
                tmp = max(tmp, calc(n-i, not flag))
        dp_T[n] = tmp
        return tmp
    if flag == False: #Yのターン-->小さくしたい
        tmp = 10 ** 10 #最大値
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n - 1: #残り0枚で相手に渡す
                tmp = min(tmp, abs(a[0] - a[n]))
            else:
                tmp = min(tmp, calc(n-i, not flag))
        dp_F[n] = tmp
        return tmp

print (calc(N, True))


Fixed submission:
import sys
sys.setrecursionlimit(10 ** 5)

N, Z, W = map(int, input().split())
a = list(map(int, input().split()))
a.reverse()
a += [W] #最後にYさんの手札を加えておく
dp_T = [-1] * (N + 1) #Xの手番
dp_F = [-1] * (N + 1) #Yの手番

def calc(n, flag): #n: 残りの山の枚数　flag: ターンの管理
    #既に計算済みの場合その値を返す
    if flag == True and dp_T[n] != -1:
        return dp_T[n]
    if flag == False and dp_F[n] != -1:
        return dp_F[n]

    if n == 1: #山の残り枚数が1枚の時 -->引くしかなく得点が決定
        return abs(a[0] - a[n])
    if flag == True: #Xのターン-->大きくしたい
        tmp = 0
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n: #残り枚数0で相手に渡す = 自分が最後の1枚を引く -->相手の手札が決まっているから得点が決定
                tmp = max(tmp, abs(a[0]-a[n]))
            else: #残り枚数が1枚以上ある時、手番は相手に変える
                tmp = max(tmp, calc(n-i, not flag))
        dp_T[n] = tmp
        return tmp
    if flag == False: #Yのターン-->小さくしたい
        tmp = 10 ** 10 #最大値
        for i in range(1, n + 1): #自分が引く枚数 = 1 ~ n枚
            if i == n - 1: #残り0枚で相手に渡す
                tmp = min(tmp, abs(a[0] - a[n]))
            else:
                tmp = min(tmp, calc(n-i, not flag))
        dp_F[n] = tmp
        return tmp

print (calc(N, True))