阿里巴巴2014校园招聘笔试最后一道题目

题目:在黑板上写下50个数字:1至50,在接下来的49轮操作中,每次做如下动作:选取两个黑板上的数字a和b,擦去,在黑板上写|b-a|。请问最后一次动作之后剩下的数字可能是什么?为什么?(不用写代码,不写原因不得分)。

答案:1-49之间的奇数。

原因:由于这50个数当中有25个奇数,相减的过程中,奇数可能两两消失,也可能不消失,因此最后剩的数一定是奇数。那么如何得到一个特定的奇数呢,以37和39为例子。

37: 以38为中枢,分成两块,横线连接的两个数两两相减      1 2_3 4_5  6_7 ... 36_37 38 39_40 41_42 ...49_50,得到一个序列:1,1,1……1, 38,1,1.……1,其中38前面有19个1,后面有10个1,再将相邻的1两两相减,最后得到1,38,然后这两个数相减得到37.

39:也是一样的道理,以40为中枢,分成两块,前面两两相减可以得到20个1,后面可以得到5个1,最后得到40, 1,这两个数相减,得到39.

对于特定的奇数X,只需要以X+1为中枢,分成两块,然后相邻的数两两相减,全化为1,再两两相减,最后得到X+1和1,相减就可以得到X


我的分析:由于擦除数字的随机性,最后一定不是某个具体的数字,唯独能确定的是奇数还是偶数。 

我的答案:最后是个奇数,原因如下: 

首先对可能擦除的种类进行分析,有三种可能: 
1. 擦除两个奇数 Num1 和Num2, 擦除后新增一个偶数 Num3 = |Num1 - Num2| 
在这种情况下 Num1 + Num2 - |Num1 - Num2| 是偶数,也就是说,这种情况下,黑板上现有数字的总和会减少一个偶数值( Num1 + Num2 - |Num1 - Num2| ) 

2. 擦除两个偶数Num1 和 Num2, 擦除后新增一个偶数Num3 = |Num1 -Num2| 
在这种情况下 Num1 + Num2 - |Num1 - Num2| 是偶数,也就是说,这种情况下,黑板上现有数字的总和会减少一个偶数值( Num1 + Num2 - |Num1 - Num2| ) 

3. 擦除一个偶数(Num1)一个奇数(Num2), 擦除后新增一个奇数Num3 = |Num1 - num2|, 在这种情况下 Num1 + Num2 - |Num1 - Num2| 还是一个偶数,也就是说,这种情况下,黑板上现有数字的总和会减少一个偶数值( Num1 + Num2 - |Num1 - Num2| ) 

上述三种可能的情况可以看出,不管是哪一种情况,每次操作都将减少一个偶数差值。(Num1 + Num2 - |Num1 - Num2|) 

这样,最后剩余的一个数是奇数还是偶数,我们只要看一下1到50的总和是奇数还是偶数即可。 

1到50的和是1275,是一个奇数,这样我们便可以知道最后一个数一定是一个奇数,因为每次擦除操作减少的都是一个偶数差值(Num1 + Num2 - |Num1 - Num2|)。 

下面用程序来运行一下,也能发现最后的数字是一个奇数。 

package my.thread;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

/**
 * 
 * @author Eric
 * 
 */
public class AlibabaExample {

	public static void main(String[] args) {

		AlibabaExample example = new AlibabaExample();

		int lastIntValue = 0;
		for (int i = 0; i < 100; i++) {
			lastIntValue = example.populateLastRemainingNumber();
			System.out.println(String.format("第%d次运行,最后剩余的数是--> %d, 是个%s",
					i + 1, lastIntValue, lastIntValue % 2 == 0 ? "偶数" : "奇数"));
		}
	}

	public int populateLastRemainingNumber() {
		List<Integer> intList = initList();

		Random ran = new Random();
		int size = 0;

		int ranIndex1 = 0;
		int ranIndex2 = 0;

		int num1 = 0;
		int num2 = 0;

		for (int i = 0; i < 49; i++) {

			size = intList.size();

			ranIndex1 = ran.nextInt(size);

			while (true) {
				ranIndex2 = ran.nextInt(size);
				if (ranIndex1 != ranIndex2) {
					break;
				}
			}
			num1 = intList.get(ranIndex1);
			num2 = intList.get(ranIndex2);
			intList.remove(ranIndex1);

			if (ranIndex1 > ranIndex2) {
				intList.remove(ranIndex2);
			} else {
				intList.remove(ranIndex2 - 1);
			}

			intList.add(Math.abs(num1 - num2));
		}

		return intList.get(0);
	}

	private List<Integer> initList() {
		List<Integer> intList = new LinkedList<Integer>();

		for (int i = 1; i < 51; i++) {
			intList.add(i);
		}

		return intList;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值