`
410063005
  • 浏览: 179998 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

算法小练习-根据上排数求下排数

 
阅读更多

 

 

参考 http://blog.csdn.net/wcyoot/article/details/6428305

 

1. 问题

 

给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数   

要求下排每个数都是先前上排那十个数在下排出现的次数。   

上排的十个数如下:   

【0,1,2,3,4,5,6,7,8,9】

举一个例子,   

数值: 0,1,2,3,4,5,6,7,8,9   

分配: 6,2,1,0,0,0,1,0,0,0   

0在下排出现了6次,1在下排出现了2次,   

2在下排出现了1次,3在下排出现了0次....   

以此类推..   

 

2. 分析

关键是理解“要求下排每个数都是先前上排那十个数在下排出现的次数”。

做以下分析:设总共有n个数,上排a[0...n-1],下排b[0...n-1],。

1)下排n个数的累加和为n,即b[0]+b[1]+...+b[n-1] = n

2)ai*bi的累加和也为n,即a[0]*b[0]+a[1]*b[1]+...+a[n-1]*b[n-1] = n

3)对于b中任意一个元素b[j], 都存在i,a[i] = b[j].

 

还可以分析出更多的限制条件,这里就不继续了。

可参考http://blog.csdn.net/wcyoot/article/details/6428305

 

根据以上分析,可以看出其实这个题目的本质是一个多元一次不定方程。在未知数较少,分析出的限制条件越多的情况下,手算出结果是完全可能的。下面根据以上条件给出代码

 

3. 代码

思路:

依次将下排数组b的最后一个元素值设置为上排数组a的第i个元素值;

如果满足条件2), 则两个数组大小减1, 递归这个过程。

如果数组大小为0, 说明递归结束, 检查条件1)和2)是否满足, 若满足则打印出结果。

 

# -*- coding: utf-8 -*-

# 求两个列表的乘积和
def list_sum(a, b):
	size = len(a)
	c = [a[i] * b[i] for i in range(0, size)]
	#print c
	return sum(c)

# 检查a每个元素中每个元素在b中出现的次数是否满足要求
def check(a, b):
	for i in range(len(a)):
		if b.count(a[i]) != b[i]:
			return False		
	return True

# a 上排数组
# b 下排数组
# target 目标和(列表大小)
# size 列表当前大小
def calc(a, b, target, size):
	if 0 == size:
		if sum(b) == target and list_sum(a, b) == target:
			#print b, check(a, b)
			if check(a, b):
				print a
				print b
				print '*' * 10
		return
		
	for i in range(0, target):
		b[size - 1] = a[i]
		if b[size - 1] * a[size - 1] <= target:
			calc(a, b, target, size - 1)
	
if __name__ == '__main__':
	'''
	a = [0,1 , 2, 3, 4, 5, 6, 7, 8, 9]
	b = [0 for i in range(0, 10)]
	calc(a, b, 10, 10)
	'''
	
	
	a = [0,1 , 2, 3, 4, 5, 6, 7]
	b = [0 for i in range(0, 8)]
	calc(a, b, 8, 8)
	
	'''
	# 上排无0, 全0解
	a = [1 , 2, 3, 4, 5, 6, 7, 8]
	b = [0 for i in range(0, 8)]
	calc(a, b, 8, 8)
	'''

 

运行结果如下


 

  • 大小: 11.4 KB
0
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics