码迷,mamicode.com
首页 > 其他好文 > 详细

Codility: EvenSumsGame

时间:2016-05-13 01:05:50      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:

Question

Even sums is a game for two players. Players are given a sequence of N positive integers and take turns alternately. In each turn, a player chooses a non-empty slice (a subsequence of consecutive elements) such that the sum of values in this slice is even, then removes the slice and concatenates the remaining parts of the sequence. The first player who is unable to make a legal move loses the game.

You play this game against your opponent and you want to know if you can win, assuming both you and your opponent play optimally. You move first.

Write a function:

def solution(A)
that, given a zero-indexed array A consisting of N integers, returns a string of format “X,Y” where X and Y are, respectively, the first and last positions (inclusive) of the slice that you should remove on your first move in order to win, assuming you have a winning strategy. If there is more than one such winning slice, the function should return the one with the smallest value of X. If there is more than one slice with the smallest value of X, the function should return the shortest. If you do not have a winning strategy, the function should return “NO SOLUTION”.

For example, given the following array:

A[0] = 4
A[1] = 5
A[2] = 3
A[3] = 7
A[4] = 2
the function should return “1,2”. After removing a slice from positions 1 to 2 (with an even sum of 5 + 3 = 8), the remaining array is [4, 7, 2]. Then the opponent will be able to remove the first element (of even sum 4) or the last element (of even sum 2). Afterwards you can make a move that leaves the array containing just [7], so your opponent will not have a legal move and will lose. One of possible games is shown on the following picture:

Note that removing slice “2,3” (with an even sum of 3 + 7 = 10) is also a winning move, but slice “1,2” has a smaller value of X.

For the following array:

A[0] = 2
A[1] = 5
A[2] = 4
the function should return “NO SOLUTION”, since there is no strategy that guarantees you a win.

Assume that:

N is an integer within the range [1..100,000];
each element of array A is an integer within the range [1..1,000,000,000].
Complexity:

expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.


Analysis

这个的重点就在于取完连续的 subarray 后,是什么样的形式保证必赢。 形式应该是要么为空,要么只剩下一个奇数,并且该奇数左右两边的偶数的数量是相等的。

容易出错的点: 要保证 X 是最小的


Solution

# you can write to stdout for debugging purposes, e.g.
# print "this is a debug message"


def check(start, end):
    if start>end:
        res = ‘NO SOLUTION‘
    else:
        res = str(start) + ‘,‘ + str(end)

    return res

def trans( strr ):
    if strr ==‘NO SOLUTION‘:
        return (-1, -1)
    else:
        a, b = strr.split(‘,‘)
        return ( int(a), int(b) )


def solution(A):
    # write your code in Python 2.7

    odd_list = [ ind for ind in range(len(A)) if A[ind]%2==1 ] 

    if len(odd_list)%2==0:
        return check(0, len(A)-1)


    odd_list = [-1] + odd_list + [len(A)]
    res_cand = []
    # the numbers at the either end of A are even
    count = odd_list[1]
    second_count = len(A)-1-odd_list[-2]
    first_count = odd_list[2]-odd_list[1]-1
    if second_count >= count:
        res_cand.append(  trans(check( odd_list[1]+1, len(A)-1-count )))

    if first_count >= count:
        res_cand.append(  trans(check( odd_list[1]+count+1, len(A)-1 )))  

    twosum = first_count + second_count
    if second_count < count <= twosum:
        res_cand.append(  trans(check( odd_list[1]+(first_count-(count-second_count))+1, odd_list[-2] )))

    ###########################################
    count = len(A)-1-odd_list[-2]
    first_count = odd_list[1]
    second_count = odd_list[-2]-odd_list[-3]-1
    if first_count >= count:
        res_cand.append(  trans(check( count, odd_list[-2]-1 )))

    if second_count >= count:
        res_cand.append(  trans(check( 0, odd_list[-2]-count-1)) )

    twosum = first_count + second_count
    if second_count < count <= twosum:
        res_cand.append(  trans(check( count-second_count, odd_list[-3])) )



    res_cand = sorted( res_cand, key=lambda x: (-x[0],-x[1]) )

    cur = (-1, -2)
    for item in res_cand:
        if item[0]!=-1:
            cur = item

    return check( cur[0], cur[1] )

Codility: EvenSumsGame

标签:

原文地址:http://blog.csdn.net/ayst123/article/details/51345482

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!