Python刷OJ———UVa:1594 Ducci Sequence

题干

A Ducci sequence is a sequence of n-tuples of integers. Given an n-tuple of integers (a1, a2, · · · , an),
the next n-tuple in the sequence is formed by taking the absolute differences of neighboring integers:
(a1, a2, · · · , an) → (|a1 − a2|, |a2 − a3|, · · · , |an − a1|)
Ducci sequences either reach a tuple of zeros or fall into a periodic loop. For example, the 4-tuple
sequence starting with 8,11,2,7 takes 5 steps to reach the zeros tuple:
(8, 11, 2, 7) → (3, 9, 5, 1) → (6, 4, 4, 2) → (2, 0, 2, 4) → (2, 2, 2, 2) → (0, 0, 0, 0).
The 5-tuple sequence starting with 4,2,0,2,0 enters a loop after 2 steps:
(4, 2, 0, 2, 0) → (2, 2, 2, 2, 4) → (0,0,0,2,2) → (0, 0, 2, 0, 2) → (0, 2, 2, 2, 2) → (2, 0, 0, 0, 2) →
(2, 0, 0, 2, 0) → (2, 0, 2, 2, 2) → (2, 2, 0, 0, 0) → (0, 2, 0, 0, 2) → (2, 2, 0, 2, 2) → (0, 2, 2, 0, 0) →
(2, 0, 2, 0, 0) → (2, 2, 2, 0, 2) → (0, 0, 2, 2, 0) → (0, 2, 0, 2, 0) → (2, 2, 2, 2, 0) → (0,0,0,2,2) → · · ·
Given an n-tuple of integers, write a program to decide if the sequence is reaching to a zeros tuple
or a periodic loop.

Input

Your program is to read the input from standard input. The input consists of T test cases. The number
of test cases T is given in the first line of the input. Each test case starts with a line containing an
integer n (3 ≤ n ≤ 15), which represents the size of a tuple in the Ducci sequences. In the following
line, n integers are given which represents the n-tuple of integers. The range of integers are from 0 to
1,000. You may assume that the maximum number of steps of a Ducci sequence reaching zeros tuple
or making a loop does not exceed 1,000.

Output

Your program is to write to standard output. Print exactly one line for each test case. Print ‘LOOP’ if
the Ducci sequence falls into a periodic loop, print ‘ZERO’ if the Ducci sequence reaches to a zeros tuple.

Sample Input

4
4
8 11 2 7
5
4 2 0 2 0
7
0 0 0 0 0 0 0
6
1 2 3 1 2 3

Sample Output

ZERO
LOOP
ZERO
LOOP

————————————————————————————————————————————

题目就不解读了,自行翻译

思路

这道题在网上搜到的代码100%都是c/c++的,而其中绝大部分人的做法是:
直接按照题目所说模拟,也就是循环计算1000次,用map并发多线程
然后就AC了。没错这道题很水,

于是我也用同样的写法,循环加map。不出所料的超时!!
木得办法,Python还是慢呀,而且众所周知,因为GIL锁的问题,python多线程实际是单线程。

上一下代码先,然后再说解决办法:

T = int(input())
list_dc = [[] for _ in range(T)]
for t in range(T):
    n = int(input())
    list_dc[t] = list(map(int, input().split(' ')))


def Recursion(du):
    length = len(du) - 1
    for m in range(200):
        for k in du:
            if k != 0:
                break
        else:
            return 'ZERO'
        du_c = [v for v in du]
        for j in range(length):
            du[j] = abs(du_c[j] - du_c[j + 1])
        du[length] = abs(du_c[length] - du_c[0])
    for e in du:
        if e != 0:
            return 'LOOP'
    else:
        return 'zero'


result = map(Recursion, list_dc)
for i in result:
    print(i)

我尝试各种改进,可终究是杯水车薪,时间终究不能有质的飞跃。
正当打算放弃时,偶然看到一个帖子,帖子里说其实只需要计算200次就可以了
我的第一反应是用了什么算法,或者推导出数列本身的性质了

但是稍微一分析,便知道绝对不是数列本身性质,因为按照题目条件,最坏就是数列中的整数全都是1000,这样真的就要循环1000次才能发现是zero。

而对于算法我是无可奈何,于是抱着试一试的心态,我直接把1000改为了200次循环
竟然成功了!!!
在这里插入图片描述
这道题的限制时间是3s,所以也是很极限了。
——————————————————————————
由此看来,应该是判题系统的数据水了。。。钻了个空子
至于这位大神是如何发现的,实在不得而知,佩服

在循环1000的代码下,我自己曾拿T = 1100(1100个测试数列)测试过,时间是符合的
所以可见这道题官方的测试数据应该有很多很多组,注重于如何快速处理更多组的数据,于是在数列数字的大小上放松了

发布了29 篇原创文章 · 获赞 74 · 访问量 2084

猜你喜欢

转载自blog.csdn.net/CxsGhost/article/details/104090746
今日推荐