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新手,如何使用for循环编写此代码?我不想使用for循环,因为我得到了一个错误。提前谢谢 问题是: 考虑序列序列=(1,2,…,n)。您应该选择此序列的两个元素并交换它们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
如果存在整数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