Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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 在N*N矩阵中查找总数据_Python_Algorithm - Fatal编程技术网

Python 在N*N矩阵中查找总数据

Python 在N*N矩阵中查找总数据,python,algorithm,Python,Algorithm,矩阵由N×N个块组成。块数等于行数和列数之和。每个块由数据组成,数据等于块号的奇偶数字之和的差。计算n*n个块的总数据 i/o格式 因此,总数据=2+3+4+5+3+4+5+6+4+5+6+7+5+6+7+8=80 如果块的数量在任何情况下为4256,则其中的数据将是abs(差(和(偶数)-和(奇数)),即abs((4+2+6)-(5))=7 我天真的尝试 n = int(raw_input()) sum1=0 sum2=0 for i in range(1,n+1): for j in

矩阵由N×N个块组成。块数等于行数和列数之和。每个块由数据组成,数据等于块号的奇偶数字之和的差。计算n*n个块的总数据

i/o格式

因此,总数据=2+3+4+5+3+4+5+6+4+5+6+7+5+6+7+8=80

如果块的数量在任何情况下为4256,则其中的数据将是abs(差(和(偶数)-和(奇数)),即abs((4+2+6)-(5))=7

我天真的尝试

n = int(raw_input())
sum1=0
sum2=0
for i in range(1,n+1):
    for j in range(1,n+1):
        sum1 = i+j
        diffsum = diff(sum1)
        sum2 = sum2+diffsum
print sum2
再次优化尝试


在这两种情况下,diff都是通用函数。我需要使用以下算法进行更多的优化

您的优化方法只对每个数字计算一次数字和,因此乍一看,从记忆中没有任何收获

通过将两个循环合并为一个循环,并使用字典查找是否添加或减去数字,可以提高
diff
函数的性能:

value = dict(zip("0123456789", (0, -1, 2, -3, 4,-5, 6,-7, 8,-9)))

def diff2(s):
    s = str(s)
    return abs(sum([value[i] for i in s]))
这将需要转换为字符串。通过手动计算数字,您可以更快(但不是更多):

dvalue = [0, -1, 2, -3, 4,-5, 6,-7, 8,-9]

def diff(s):
    t = 0

    while s:
        t += dvalue[s % 10]
        s //= 10

    return abs(t)
最后,您可以利用这样一个事实,即按顺序计算从2到2·n的所有数字和。将当前数字的数字存储在数组中,然后实现类似里程表的计数器。当您递增该计数器时,请跟踪奇数和偶数之和。在10种情况中的9种情况下,您只需调整最后一个数字,将其值从相应的总和中移除,然后将下一个数字添加到另一个总和中

这里有一个程序可以做到这一点。函数
next
递增计数器,并在
sums[0]
sums[1]
中保留偶数和奇数的数字和。主程序基本上与您的程序相同,只是循环被分为两部分:一部分是
k
增加,另一部分是减少

even = set(range(0, 10, 2))

def next(num, sums):    
    o = num[0]
    if o in even:
        sums[0] -= o
        sums[1] += o + 1
    else:
        sums[0] += o + 1
        sums[1] -= o

    num[0] += 1

    i = 0
    while num[i] == 10:
        sums[0] -= 10
        num[i] = 0

        i += 1
        o = num[i]
        if o in even:
            sums[0] -= o
            sums[1] += o + 1
        else:
            sums[0] += o + 1
            sums[1] -= o

        num[i] += 1

n = int(raw_input())
total = 0

m = len(str(2 * n + 1))
num = [0] * m
num[0] = 2
sums = [2, 0]

k = 1
for i in range(2, n + 2):
    total += abs(sums[0] - sums[1]) * k
    k += 1
    next(num, sums)    

k = n        
for i in range(n + 2, 2*n + 1):
    k -= 1        
    total += abs(sums[0] - sums[1]) * k
    next(num, sums)

print total
我在上面说过,回忆录对这种方法没有用处。那不是真的。您可以存储数字
i
的偶数和奇数总和,并在计算
10*i
10*i+9
的数字时使用它。当您按增加
i
的顺序调用
diff
时,您将可以访问存储的
i//10
的总和

def diff(s):
    d = s % 10

    e = ememo[s / 10]
    o = omemo[s / 10]

    if d in even:
        e += d
    else:
        o += d

    if s < smax:
        ememo[s] = e 
        omemo[s] = o    

    return e, o

n = int(raw_input())

total = 0

even = set(range(0, 10, 2))
smax = (2*n + 11) / 10
omemo = smax * [0]
ememo = smax * [0]
omemo[1] = 1

k = 1    
for i in range(2, n + 2):
    e, o = diff(i)
    total += abs(e - o) * k
    k += 1        

k = n        
for i in range(n + 2, 2*n + 1):
    k -= 1   
    e, o = diff(i)     
    total += abs(e - o) * k

print total
这并不比里程表的方法快多少,但以额外内存为代价,实现起来更清晰。(对于大的
n
,预分配数组比字典工作得更好。您不需要为
(2*n+11)/10上面的数字保留空间)

def差异:
d=s%10
e=ememo[s/10]
o=omemo[s/10]
如果d为偶数:
e+=d
其他:
o+=d
如果s

如果能找到一个数字和的闭合公式,这可能会更快,但我认为绝对函数阻止了这种解决方案。

thanx顺便说一句,但我们可以通过计算您所使用的公式来做得更好telling@bosey:如果你能用一个封闭式公式来求解,那当然是最有效的了。然而,我还没有找到这样一个公式,我认为
sum(|奇偶|)
中的绝对函数使得找到这样一个公式很困难。
even = set(range(0, 10, 2))

def next(num, sums):    
    o = num[0]
    if o in even:
        sums[0] -= o
        sums[1] += o + 1
    else:
        sums[0] += o + 1
        sums[1] -= o

    num[0] += 1

    i = 0
    while num[i] == 10:
        sums[0] -= 10
        num[i] = 0

        i += 1
        o = num[i]
        if o in even:
            sums[0] -= o
            sums[1] += o + 1
        else:
            sums[0] += o + 1
            sums[1] -= o

        num[i] += 1

n = int(raw_input())
total = 0

m = len(str(2 * n + 1))
num = [0] * m
num[0] = 2
sums = [2, 0]

k = 1
for i in range(2, n + 2):
    total += abs(sums[0] - sums[1]) * k
    k += 1
    next(num, sums)    

k = n        
for i in range(n + 2, 2*n + 1):
    k -= 1        
    total += abs(sums[0] - sums[1]) * k
    next(num, sums)

print total
def diff(s):
    d = s % 10

    e = ememo[s / 10]
    o = omemo[s / 10]

    if d in even:
        e += d
    else:
        o += d

    if s < smax:
        ememo[s] = e 
        omemo[s] = o    

    return e, o

n = int(raw_input())

total = 0

even = set(range(0, 10, 2))
smax = (2*n + 11) / 10
omemo = smax * [0]
ememo = smax * [0]
omemo[1] = 1

k = 1    
for i in range(2, n + 2):
    e, o = diff(i)
    total += abs(e - o) * k
    k += 1        

k = n        
for i in range(n + 2, 2*n + 1):
    k -= 1   
    e, o = diff(i)     
    total += abs(e - o) * k

print total