Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加速完美交换计算-避免循环 导入系统 t=(int(sys.stdin.readline()) 对于范围(0,t)内的i: n=int(sys.stdin.readline()) c=0 s=n*(n+1)/2 如果是%2=0: 打印(0) 其他: c=0 i=-1 a=[i代表范围(1,n+1)内的i] h=s//2 m=0 s1=0 对于范围(n-1,-1,-1)内的i: s1+=a[i] c+=1 如果s1==h: m=1 打破 如果s1>h: 打破 如果m==1: s1=((c+1)*(2+((c-1)-1))//2+((n-c-1)*(2+((n-c-1)-1))//2 打印(s1) 其他: 印刷品(c)_Python_Python 3.x_Python 2.7 - Fatal编程技术网

Python 加速完美交换计算-避免循环 导入系统 t=(int(sys.stdin.readline()) 对于范围(0,t)内的i: n=int(sys.stdin.readline()) c=0 s=n*(n+1)/2 如果是%2=0: 打印(0) 其他: c=0 i=-1 a=[i代表范围(1,n+1)内的i] h=s//2 m=0 s1=0 对于范围(n-1,-1,-1)内的i: s1+=a[i] c+=1 如果s1==h: m=1 打破 如果s1>h: 打破 如果m==1: s1=((c+1)*(2+((c-1)-1))//2+((n-c-1)*(2+((n-c-1)-1))//2 打印(s1) 其他: 印刷品(c)

Python 加速完美交换计算-避免循环 导入系统 t=(int(sys.stdin.readline()) 对于范围(0,t)内的i: n=int(sys.stdin.readline()) c=0 s=n*(n+1)/2 如果是%2=0: 打印(0) 其他: c=0 i=-1 a=[i代表范围(1,n+1)内的i] h=s//2 m=0 s1=0 对于范围(n-1,-1,-1)内的i: s1+=a[i] c+=1 如果s1==h: m=1 打破 如果s1>h: 打破 如果m==1: s1=((c+1)*(2+((c-1)-1))//2+((n-c-1)*(2+((n-c-1)-1))//2 打印(s1) 其他: 印刷品(c),python,python-3.x,python-2.7,Python,Python 3.x,Python 2.7,我是python新手,如何使用for循环编写此代码?我不想使用for循环,因为我得到了一个错误。提前谢谢 问题是: 考虑序列序列=(1,2,…,n)。您应该选择此序列的两个元素并交换它们 如果存在整数o(1),则交换是完美的≤o到目前为止,我对这个问题产生了兴趣,并发现: 创建列表并真正交换元素的慢版本是: from itertools import combinations def slow(N): found = 0 for i, j in combinations(ra

我是python新手,如何使用for循环编写此代码?我不想使用for循环,因为我得到了一个错误。提前谢谢

问题是:

考虑序列序列=(1,2,…,n)。您应该选择此序列的两个元素并交换它们


如果存在整数o(1),则交换是完美的≤o到目前为止,我对这个问题产生了兴趣,并发现:

创建列表并真正交换元素的慢版本是:

from itertools import combinations

def slow(N):

    found = 0
    for i, j in combinations(range(N), 2):

        lst = list(range(1, N + 1))
        lst[i], lst[j] = lst[j], lst[i]

        for m in range(1, N):
            a = m * (m + 1) // 2
            b = (N - m) * (N + m + 1) // 2
            if i < m <= j:
                a = a - i + j
                b = b - j + i

            assert a == sum(lst[:m])
            assert b == sum(lst[m:])

            if sum(lst[:m]) == sum(lst[m:]):
                found += 1

                if i < m <= j:
                    assert 2 * m * (m + 1) + 4 * j == N * (N + 1) + 4 * i
                else:
                    assert 2 * m * (m + 1) == N * (N + 1)

            else:
                if i < m <= j:
                    assert 2 * m * (m + 1) + 4 * j != N * (N + 1) + 4 * i
                else:
                    assert 2 * m * (m + 1) != N * (N + 1)
    return found
所有这些都可以用一些基本的数学计算出来


从这一点开始,你可以做更多的数学运算,并看到有两种情况需要考虑:

  • 存在一个
    m
    ,使得原始列表
    [1,2,3,…,m,m+1,…,N]
    m
    的总和等于列表其余部分的总和(例如
    N=20;m=14
    )。再次出现两种情况:

  • 所有不跨越
    m
    边界的掉期都是有效的(有
    comb(m,2)+comb((N-m,2)
  • 当您在
    m-1
    进行拆分时,您将发现更多的掉期;这一次您必须跨
    m-1
    边界进行掉期账户
  • 在这种情况下,
    m
    根据

    m = - 1 + sqrt(1 + 2 * N * (N + 1)) / 2
    
    < > > < <代码> m <代码>在第一种情况下不是整数(即代码>1+2×n*(n+1)< /代码>不是完美的正方形)。然后考虑<代码> m <代码>,然后是上述公式的结果(我使用<代码> int >代码>而不是<代码>数学> Load ).对于两次拆分之和的
    diff
    差异,再次出现两种情况:

  • 差别甚至更大:需要跨越
    m
    边界的掉期交易更多
  • 差异是奇数:没有额外的交换(交换将始终导致偶数差异)
  • 代码如下:

    from math import sqrt, comb
    
    def fast(N):
        found = 0
    
        arg = (1 + 2 * N * (N + 1))
        sq = round(sqrt(arg))
        if sq ** 2 == arg and sq & 1:
            m = (-1 + sq) // 2
            found += comb(m, 2) + comb((N - m), 2)
    
            m -= 1
            found += N - m - 1
        else:
            m = int((-1 + sqrt(arg)) // 2)
            diff = ((m + 1 + N) * (N - m) - m * (m + 1)) // 2
            if diff & 1 == 0:
                found += N - m
    
        return found   
    

    什么是TLE?你的代码应该做什么?你能把代码简化到必要的最低限度吗?(例如,
    n=int(sys.stdin.readline())
    这里没有意义…。我对循环计算了3次。你想把它们全部去掉吗?最重要的是:为什么?如果你遇到了“超过时间限制”的错误,(我想这就是TLE的意思?)然后你想让你的程序更有效率。如果你想做的事情需要重复,那么不使用for循环不会提高效率。你到底想实现什么?@hiroprogator bro TLE是时间限制超过错误。所以为了摆脱这个问题,我不希望给定代码中有任何for循环,所以我的问题是如何编写相同的代码没有使用任何for循环?如果你想知道如何加快代码速度,你可能想添加你想解决的问题…它不会显示任何TLE错误。你使用了什么输入,我想我们需要更多信息。感谢你的努力。我将尝试完成其余未完成的部分。很好。再次感谢。@Akashn您是否有一些
    N
    的结果,以便我可以验证我真正需要计数的是什么?N-3输出-2,n4输出-2输入7,输出-3,N-20输出-112
    m = - 1 + sqrt(1 + 2 * N * (N + 1)) / 2
    
    from math import sqrt, comb
    
    def fast(N):
        found = 0
    
        arg = (1 + 2 * N * (N + 1))
        sq = round(sqrt(arg))
        if sq ** 2 == arg and sq & 1:
            m = (-1 + sq) // 2
            found += comb(m, 2) + comb((N - m), 2)
    
            m -= 1
            found += N - m - 1
        else:
            m = int((-1 + sqrt(arg)) // 2)
            diff = ((m + 1 + N) * (N - m) - m * (m + 1)) // 2
            if diff & 1 == 0:
                found += N - m
    
        return found