[从头学数学] 第41节 万以内的加法和减法(二)

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入练气期第五层功法的修炼,
这次要修炼的目标是[万以内的加法和减法(二)]。

正剧开始:

星历2016年01月13日 14:52:52, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[万以内的加法和减法(二)]。


这一层功法,[人叫板老师]举的是动物的计数例子:



[从头学数学] 第41节 万以内的加法和减法(二)_第1张图片


<span style="font-size:18px;">function myDraw() {  
    var config = new PlotConfiguration();  
    config.init();  
    config.setPreference(); 
	//config.setSector(1,1,1,1);
 
    //config.axis2D(0, 0, 180);  
	
	var vertExp = new VerticalExpression();
	var r = 25;
	var x = 200, y=20;
	
	vertExp.add(271, 122, x, y, r);
	
	x = 400;
	vertExp.add(271, 31, x, y, r);
	
	x = 600;
	vertExp.add(271, 903, x, y, r);	
	
}</span>

[从头学数学] 第41节 万以内的加法和减法(二)_第2张图片

[从头学数学] 第41节 万以内的加法和减法(二)_第3张图片


[从头学数学] 第41节 万以内的加法和减法(二)_第4张图片

<span style="font-size:18px;">function myDraw() {  
    var config = new PlotConfiguration();  
    config.init();  
    config.setPreference(); 
	//config.setSector(1,1,1,1);
 
    //config.axis2D(0, 0, 180);  
	
	var vertExp = new VerticalExpression();
	var row = 1, col=2, width = 600, height = 400;
	var r = 50;
	var x = 0, y=20;
	
	quest = [[445,298],[298,445]];
	len = quest.length;
	
	for (var i = 0; i < row;  i++) {
		for (var j=0; j < col; j++) {
			x = width/col*(j+1);
			y = 20 + height/row*i;
			vertExp.add(quest[i*col+j][0], quest[i*col+j][1], x, y, r);
		}
	}
	
	
}
</span>

接着[人叫板老师]让小伟给一位叫做小君的小朋友规划一下行走路线:

[从头学数学] 第41节 万以内的加法和减法(二)_第5张图片

上一次,小伟出发后并没有回家,这次不同了,而且还有了新的要求,小君要去的地方还真多。

小伟给小君的建议是:

<span style="font-size:18px;">小君家-->邮局-->小君家 ,这条路总长:436米。
小君家-->学校-->小君家 ,这条路总长:820米。
小君家-->超市-->小君家 ,这条路总长:1020米。
小君家-->邮局-->超市-->小君家 ,这条路总长:1057米。
小君家-->学校-->超市-->小君家 ,这条路总长:1045米。
小君家-->超市-->邮局-->小君家 ,这条路总长:1057米。
小君家-->超市-->学校-->小君家 ,这条路总长:1045米。
小君家-->邮局-->书店-->超市-->小君家 ,这条路总长:1243米。----有效。
小君家-->邮局-->超市-->学校-->小君家 ,这条路总长:1082米。
小君家-->学校-->超市-->邮局-->小君家 ,这条路总长:1082米。
小君家-->超市-->书店-->邮局-->小君家 ,这条路总长:1243米。----有效。
小君家-->邮局-->书店-->超市-->学校-->小君家 ,这条路总长:1268米。----有效。
小君家-->学校-->超市-->书店-->邮局-->小君家 ,这条路总长:1268米。----有效。</span>

看来这次小君这1243米的路是省不了的了。

<span style="font-size:18px;">function myDraw() {  
    var config = new PlotConfiguration();  
    config.init();  
    config.setPreference(); 
	//config.setSector(1,1,1,1);
 
    //config.axis2D(0, 0, 180);  	

	/*
		求解以下问题:
		(1)有五个地点,编号1-5,地点之间的连通情况为边数组
	*/
	//顶点数量
	var vertexNum = 5;
	var edge = [[1,2,218],[1,5,410],[1,4,510],[2,3,75],[3,4,440],[2,4,329],[4,5,125]];
	var edges = edge.length;
	
	var pathMap = new Map();
	
	for (var i = 0; i < edges; i++) {
		pathMap.put(edge[i][0], edge[i][1]);
		pathMap.put(edge[i][1], edge[i][0]);

	}

	
	/*
		(2)现在要求给出从地点1出发,回到地点1,中间经过(2, 3, 4)点,
		求出所有满足要求的选择
	*/
	var begin = 1;
	var end = 1;
	//要求经过的地点
	var required = [1, 2, 3, 4];
	
	//可增长的路径
	var pathArray = new Array();
	//pathArray中的一个选择
	var choice = new Array();
	//choice前提下的下一步选择
	var newChoice = new Array();
	//有效路径
	var effectivePath = new Array();
	//临时变量
	var tmp = 0, len = 0, len1 = 0;
	var distance = 0;
	
	//把起点压入栈
	pathArray.push([begin]);	

	while (pathArray.length > 0) {
		
		//每次从选择集合中取出第一个选择

		choice = pathArray.shift();
		len = choice.length;
		if (len > vertexNum) 
			break;

		//选择的最后一个元素
		tmp = choice[len-1];
		newChoice = pathMap.get(tmp);
		//document.write(choice.join(',')+'------'+newChoice.join(',')+'<br/>');
		
		len1 = newChoice.length;

		
		for (var i = 0; i < len1; i++) {
			for (var j = 0; j < len; j++) {
				//元素重复了
				if (newChoice[i] == choice[j]) {
					if (newChoice[i] == end) {
						effectivePath.push(choice.concat(newChoice[i]));
					} 
					
					break;
				}
				//无重复元素
				if (j >= len-1) {
					pathArray.push(choice.concat(newChoice[i]));
					//document.write(choice.concat(newChoice[i]).join(',')+'<br/>');
				}
			}
		}
	}
	
	var addressString = ['小君家', '邮局', '书店', '超市', '学校'];
	var s = ''; 
	len = effectivePath.length;
	
	for (var i = 0; i < len; i++) {
		distance = 0;
		choice = effectivePath[i];
		len1 = choice.length;
		for (var j = 0; j < len1-1; j++) {
			for (var k = 0; k < edges; k++) {
				if (edge[k][0] == choice[j] && edge[k][1] == choice[j+1]) {
					distance += edge[k][2];
				}
			}
		}
	
	}
	
	for (var i = 0; i < len; i++) {
		s = '';
		choice = effectivePath[i];
		len1 = choice.length;
		distance = 0;		
		
		for (var j = 0; j < len1; j++) {
			s +=addressString[choice[j]-1];
			if (j < len1-1) {
				s += '-->';
			}
		}
		
		for (var j = 0; j < len1-1; j++) {
			for (var k = 0; k < edges; k++) {
				if ((edge[k][0] == choice[j] && edge[k][1] == choice[j+1]) ||
					(edge[k][1] == choice[j] && edge[k][0] == choice[j+1])) {
					distance += edge[k][2];
				}
			}
		}
		s += ' ,这条路总长:'+distance.toFixed(0)+'米。';
		
		if (effective(choice, required)) {
			s += '----有效。';
		}
		
		document.write(s+'<br/>');
	}
	
}

function effective(arrayPath, arrayRequired) {
	var array1 = new Array();
	array1 = arrayPath;
	var len1 = array1.length;
	
	var array2 = new Array();
	array2 = arrayRequired;
	var len2 = array2.length;
	
	for (var i = 0; i < len2; i++) {
		for (var j = 0; j < len1; j++) {
			if (array1[j] == array2[i])
				break;
				
			if (j >= len1-1) {
				return 0;
			}
		}
	}
	
	return 1;
}</span>


这个题怎么做呢,小伟做这种题真的很擅长:

<span style="font-size:18px;">>>> 
8+8+8+88+888= 1000
8+8+88+8+888= 1000
8+88+8+8+888= 1000
88+8+8+8+888= 1000
8+8+8+888+88= 1000
8+8+888+8+88= 1000
8+888+8+8+88= 1000
888+8+8+8+88= 1000
8+8+88+888+8= 1000
8+88+8+888+8= 1000
88+8+8+888+8= 1000
8+8+888+88+8= 1000
8+888+8+88+8= 1000
888+8+8+88+8= 1000
8+88+888+8+8= 1000
88+8+888+8+8= 1000
8+888+88+8+8= 1000
888+8+88+8+8= 1000
88+888+8+8+8= 1000
888+88+8+8+8= 1000

###
# @usage   只用数字8组成五个数,满足其和为1000
# @author  mw
# @date    2016年01月13日  星期三  13:32:22 
# @param
# @return
#
###
def tmp2():
    N = 5;
    array = [0]*N;
    a = [888, 88, 8];
    total = 0;

    while (array[N-1] < 3):
        total = 0;
        s = '';
        for i in range(N):            
            total += a[array[i]];

        if (total == 1000):
            for i in range(N):
                s += str(a[array[i]]);
                if i < N-1:
                    s += '+';
            s += '= 1000';
            print(s);
            
        array[0]+=1;
        for i in range(N-1):
            if array[i] > 2:
                array[i+1]+=1;
                array[i] = 0;
    return;
	</span>

其实就是一个888, 一个88,以及三个8相加,只不过位置可以有20种排法。



这次的货物运输,小伟进行了仔细的计算:

[从头学数学] 第41节 万以内的加法和减法(二)_第6张图片

货物一共有2198千克,如果用4次,还差398千克,那么5次行不行呢?回答是不行。

货物里最重的是

<span style="font-size:18px;">>>> b = [165, 156,394,213,294,93,68,360,280,175];
>>> max(b);
394</span>
这个数字刚好比余数398小了一点,这样就必须多出来一次。

小伟的解答是:

<span style="font-size:18px;">>>> 
165 + 280 在440和450之间。
156 + 294 在440和450之间。

def tmp3():
    a = [165, 156,394,213,294,93,68,360,280,175];
    for i in range(len(a)):
        for j in range(i+1, len(a)):
            if (a[i] + a[j] >= 440 and a[i]+a[j]<=450):
                print('{0} + {1} 在440和450之间。'.format(a[i], a[j]));
				
213 + 175 在330和450之间。
68 + 360 在330和450之间。

def tmp4():
    import math;
    a = [394,213,93,68,360,175];
    minLevel = adjacence(sum(a) / (math.ceil(sum(a)/450)+1));
    for i in range(len(a)):
        for j in range(i+1, len(a)):
            if (a[i] + a[j] >= minLevel and a[i]+a[j]<=450):
                print('{0} + {1} 在{2}和450之间。'.format(a[i], a[j], minLevel));

394, 93

最少要用6次才能搬完。</span>

下面就轮到买东西了:


<span style="font-size:18px;">>>> 
买电话, 总共110元
买书桌, 总共328元
买电话, 书桌, 总共438元
买收音机, 总共208元
买电话, 收音机, 总共318元
买风扇, 总共85元
买电话, 风扇, 总共195元
买书桌, 风扇, 总共413元
买收音机, 风扇, 总共293元
买电话, 收音机, 风扇, 总共403元
买熨斗, 总共259元
买电话, 熨斗, 总共369元
买收音机, 熨斗, 总共467元
买风扇, 熨斗, 总共344元
买电话, 风扇, 熨斗, 总共454元
买电饭锅, 总共152元
买电话, 电饭锅, 总共262元
买书桌, 电饭锅, 总共480元
买收音机, 电饭锅, 总共360元
买电话, 收音机, 电饭锅, 总共470元
买风扇, 电饭锅, 总共237元
买电话, 风扇, 电饭锅, 总共347元
买收音机, 风扇, 电饭锅, 总共445元
买熨斗, 电饭锅, 总共411元
买风扇, 熨斗, 电饭锅, 总共496元
买手表, 总共120元
买电话, 手表, 总共230元
买书桌, 手表, 总共448元
买收音机, 手表, 总共328元
买电话, 收音机, 手表, 总共438元
买风扇, 手表, 总共205元
买电话, 风扇, 手表, 总共315元
买收音机, 风扇, 手表, 总共413元
买熨斗, 手表, 总共379元
买电话, 熨斗, 手表, 总共489元
买风扇, 熨斗, 手表, 总共464元
买电饭锅, 手表, 总共272元
买电话, 电饭锅, 手表, 总共382元
买收音机, 电饭锅, 手表, 总共480元
买风扇, 电饭锅, 手表, 总共357元
买电话, 风扇, 电饭锅, 手表, 总共467元
买自行车, 总共245元
买电话, 自行车, 总共355元
买收音机, 自行车, 总共453元
买风扇, 自行车, 总共330元
买电话, 风扇, 自行车, 总共440元
买电饭锅, 自行车, 总共397元
买风扇, 电饭锅, 自行车, 总共482元
买手表, 自行车, 总共365元
买电话, 手表, 自行车, 总共475元
买风扇, 手表, 自行车, 总共450元
买外套, 总共98元
买电话, 外套, 总共208元
买书桌, 外套, 总共426元
买收音机, 外套, 总共306元
买电话, 收音机, 外套, 总共416元
买风扇, 外套, 总共183元
买电话, 风扇, 外套, 总共293元
买收音机, 风扇, 外套, 总共391元
买熨斗, 外套, 总共357元
买电话, 熨斗, 外套, 总共467元
买风扇, 熨斗, 外套, 总共442元
买电饭锅, 外套, 总共250元
买电话, 电饭锅, 外套, 总共360元
买收音机, 电饭锅, 外套, 总共458元
买风扇, 电饭锅, 外套, 总共335元
买电话, 风扇, 电饭锅, 外套, 总共445元
买手表, 外套, 总共218元
买电话, 手表, 外套, 总共328元
买收音机, 手表, 外套, 总共426元
买风扇, 手表, 外套, 总共303元
买电话, 风扇, 手表, 外套, 总共413元
买熨斗, 手表, 外套, 总共477元
买电饭锅, 手表, 外套, 总共370元
买电话, 电饭锅, 手表, 外套, 总共480元
买风扇, 电饭锅, 手表, 外套, 总共455元
买自行车, 外套, 总共343元
买电话, 自行车, 外套, 总共453元
买风扇, 自行车, 外套, 总共428元
买电饭锅, 自行车, 外套, 总共495元
买手表, 自行车, 外套, 总共463元
买洗衣机, 总共496元

def tmp6():
    N = 10;
    name = ['电话', '书桌', '收音机', '风扇', '熨斗', '电饭锅', '手表', '自行车',\
            '外套', '洗衣机'];
    price = [110,328,208,85,259,152,120,245,98,496];
    array = [0] * N;
    total = 0;

    while (array[N-1] < 2):
        total = 0;
        s = '买';
        for i in range(N):            
            total += array[i]*price[i];

        if (total < 500 and total > 0):
            for i in range(N):
                if array[i] != 0:
                    s += name[i];
                    s += ', ';
            s += '总共{0}元'.format(total);
            print(s);
            
        array[0]+=1;
        for i in range(N-1):
            if array[i] > 1:
                array[i+1]+=1;
                array[i] = 0;
    return;   </span>

[从头学数学] 第41节 万以内的加法和减法(二)_第7张图片

填数字是怎么算出来的呢?是这样的:

<span style="font-size:18px;">>>> 
989 + 109 = 1098

def tmp7():
    #圆圈
    for a in range(10):
        #方块
        for b in range(10):
            if (b == a):
                continue;
            #三角
            for c in range(1, 10):
                if c==a or c==b:
                    continue;
                if (100*a + 80 + a +\
                    100*c + 10*b + a == 1000*c+100*b+10*a+8):
                    print('{0} + {1} = {2}'\
                          .format(100*a + 80 + a,\
                                  100*c + 10*b + a,\
                                  1000*c+100*b+10*a+8));
    return;
                 </span>

本节到此结束,欲知后事如何,请看下回分解。



你可能感兴趣的:([从头学数学] 第41节 万以内的加法和减法(二))