CLOCKSYNC 문제 관련해서 질문 드립니다

  • saffron3
    saffron3

    CLOCKSYNC 문제를 python으로 풀어보고 있습니다.
    완전탐색 방법으로 접근했더니 시간초과가 되서 여기서 검색하다가 새로운 접근 방법을 알게되었습니다.

    그래서 위에서 알게 된 방법으로 다시 짰더니 예제 문제가 순식간에 풀리더군요.
    그런데 온라인 저지에 제출하니 오답 결과가 나오는데,
    혹시 코드를 보시고 어느 부분에서 오답이 발생할 수 있는건지 힌트를 주실 수 있을까요?

    # Problem ID: CLOCKSYNC
    # https://algospot.com/judge/problem/read/CLOCKSYNC
    
    from collections import defaultdict
    
    switches = [
        (0, 1, 2),
        (3, 7, 9, 11),
        (4, 10, 14, 15),
        (0, 4, 5, 6, 7),
        (6, 7, 8, 10, 12),
        (0, 2, 14, 15),
        (3, 14, 15),
        (4, 5, 7, 14, 15),
        (1, 2, 3, 4, 5),
        (3, 4, 5, 9, 13)
    ]
    
    def readline():
        return raw_input()
    
    
    def is_equal_list(_list):
        """
        Check if all items in a list are equal.
    
        Args:
            _list: a list to check
        Returns:
            True if all items are equal,
            False if not
        """
        return _list.count(_list[0]) == len(_list)
    
    
    def push_switch(switch, clock_dict, push_count):
        """
        Push the given switch and make changes to the clocks.
    
        Args:
            switch: switch to push
            clock_dict: a dictionary which tracks time on each clocks
            push_count: a number of push action to take
        """
        for e in range(push_count):
            for clock in switches[switch]:
                clock_dict[clock] += 3
                if clock_dict[clock] == 15:
                    clock_dict[clock] = 3
    
    
    def remove_pushed_switches(pushed_switches, switch_dict):
        """
        Remove pushed switches from the switch dictionary.
    
        Args:
            pushed_switches: a list of switches pushed
            switch_dict: a dictionary which has clocks as keys, and linked switches as values
        """
        for key in switch_dict.keys():
            for switch in pushed_switches:
                if switch in switch_dict[key]:
                    switch_dict[key].pop(switch_dict[key].index(switch))
    
    
    def faster_sync(switch_dict, clock_dict):
        """
        Sync the clocks by eliminating clock-switch link that has fixed number of push count.
    
        Args:
            switch_dict: a dictionary which has clocks as keys, and linked switches as values
            clock_dict: a dictionary which tracks time on each clocks
        Returns:
            minimum switch count
        """
        pushed_switches = set()
        fixed_clocks = set()
        count = 0
        # while there are still switch left to push
        while not is_equal_list(switch_dict.values()):
            for (clock, switch_list) in switch_dict.items():
                # if a clock has only one switch linked,
                # then it means it has fixed number of push count
                if len(switch_list) == 1:
                    count += ((12 - clock_dict[clock]) / 3)
                    push_switch(switch_list[0], clock_dict, (12 - clock_dict[clock]) / 3)
                    pushed_switches.add(switch_list[0])
                    fixed_clocks.add(clock)
            # if there was only one switch pushed in this iteration,
            # then all clocks with fixed count must have equal values
            if len(pushed_switches) == 1 and not is_equal_list(map(lambda clock: clock_dict[clock], fixed_clocks)):
                return float('inf')
            # if all clocks are sync, then return the count
            if is_equal_list(clock_dict.values()):
                return count
            # remove pushed switches and reset
            remove_pushed_switches(pushed_switches, switch_dict)
            pushed_switches.clear()
            fixed_clocks.clear()
        # if all clocks are sync, then return the count
        if is_equal_list(clock_dict.values()):
            return count
        else:
            return float('inf')
    
    
    def clocksync():
        total_tests = int(readline())
        for testcase in range(total_tests):
            clocks = map(int, readline().split())
            if clocks[14] != clocks[15] or clocks[8] != clocks[12]:
                print -1
            switch_dict = defaultdict(list)
            for switch in range(10):
                for clock in switches[switch]:
                    switch_dict[clock].append(switch)
            clock_dict = {}
            for clock in range(16):
                clock_dict[clock] = clocks[clock]
            inf = float('inf')
            min_switch = faster_sync(switch_dict, clock_dict)
            if min_switch == inf:
                print -1
            else:
                print min_switch
    
    
    if __name__ == '__main__':
        clocksync()  # run
    

    8년 전
2개의 댓글이 있습니다.
  • seico75
    seico75

    def is_equal_list(_list): 이 함수는 모든 시계가 동일한지를 판단하는데, 문제는 모든 시계가 12시를 가리키는지를 묻고 있네요.


    8년 전 link
  • saffron3
    saffron3

    답변 감사드립니다 seico75
    말씀하신대로 모든 시계가 12시인지 확인하는 부분에서는 정확히 12시인지 확인하도록 바꿔서 제출해보았지만 여전히 오답이 나오네요...
    아무래도 다른 부분에서 문제가 있는 것이 아닐까 싶습니다.

    def is_equal_list(_list, for_clocks=False):
        """
        Check if all items in a list are equal.
    
        Args:
            _list: a list to check
            for_clocks: a boolean value to handle clock case specifically
        Returns:
            True if all items are equal,
            False if not
        """
        return _list.count(12) == 16 if for_clocks else _list.count(_list[0]) == len(_list)
    
    def faster_sync(switch_dict, clock_dict):
        """
        Sync the clocks by eliminating clock-switch link that has fixed number of push count.
    
        Args:
            switch_dict: a dictionary which has clocks as keys, and linked switches as values
            clock_dict: a dictionary which tracks time on each clocks
        Returns:
            minimum switch count
        """
        pushed_switches = set()
        fixed_clocks = set()
        count = 0
        # while there are still switch left to push
        while not is_equal_list(switch_dict.values()):
            for (clock, switch_list) in switch_dict.items():
                # if a clock has only one switch linked,
                # then it means it has fixed number of push count
                if len(switch_list) == 1:
                    count += ((12 - clock_dict[clock]) / 3)
                    push_switch(switch_list[0], clock_dict, (12 - clock_dict[clock]) / 3)
                    pushed_switches.add(switch_list[0])
                    fixed_clocks.add(clock)
            # if there was only one switch pushed in this iteration,
            # then all clocks with fixed count must have equal values
            if len(pushed_switches) == 1 and not is_equal_list(map(lambda clock: clock_dict[clock], fixed_clocks)):
                return float('inf')
            # if all clocks are sync, then return the count
            if is_equal_list(clock_dict.values(), True):
                return count
            # remove pushed switches and reset
            remove_pushed_switches(pushed_switches, switch_dict)
            pushed_switches.clear()
            fixed_clocks.clear()
        # if all clocks are sync, then return the count
        if is_equal_list(clock_dict.values(), True):
            return count
        else:
            return float('inf')
    


    8년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.