<笔试面试>2013.9.22 阿里校招 笔试题之 在黑板上写下50个数字,1至50
2013-09-28 15:02
549 查看
2013年9月22日 阿里巴巴校招 算法、研发 题之(仅供学习讨论)
在黑板上写下50个数字:1至50,在接下来的49轮操作中,每次做如下操作,选取两个黑板上的数字a和b,擦去,在黑板上写|b-a|,请问最后一次动作之后剩下数字可能是什么?为什么?(不用写代码,不写原因不得分)。
1至n的数字,剩余的数字肯定为0至n的数字,假如剩下k,则可以这样认为,1至n的数字中除k外的数字全部抵消了。当任意选择a、b时,假如a较小,这些数字的总和将减少2a,即使是b,最后消为0时,也将减去2b,最后全部消失。所以这些数字的和一定是偶数2*m,m是这些数字中(k除外)的数字组合,如存在这个组合,那么就可以。
分析及就到此为止了,以下是我Java实现的代码,
运行结果就是1至50,可能剩余的数字
输出结果为:
就是1到50之间的奇数都有可能。
或单独查看某个数字是否能留下,一种可能是擦出顺序是,从输出的数字中,依次,从剩余的其他数字中找数字,将该数字抵消掉,直到为0.
例如,n=10,
输出:
要剩余5,可以这样:
1到10: 1、2、3、4、5、6、7、8、9、10
5要剩余,先去掉: 1、2、3、4、6、7、8、9、10
先选10,从1、2、3、4、7、8中选两个数消除掉,就8和2吧,剩下:1、3、4、6、7、9
再选9,从1、3、4、7中,选数字7、1吧,剩余1、3、4、6,
最后选6,将剩余1、3、4,想办法抵消掉,比如6-4=2、3-2=1、1-1=0,到此为止。
在黑板上写下50个数字:1至50,在接下来的49轮操作中,每次做如下操作,选取两个黑板上的数字a和b,擦去,在黑板上写|b-a|,请问最后一次动作之后剩下数字可能是什么?为什么?(不用写代码,不写原因不得分)。
1至n的数字,剩余的数字肯定为0至n的数字,假如剩下k,则可以这样认为,1至n的数字中除k外的数字全部抵消了。当任意选择a、b时,假如a较小,这些数字的总和将减少2a,即使是b,最后消为0时,也将减去2b,最后全部消失。所以这些数字的和一定是偶数2*m,m是这些数字中(k除外)的数字组合,如存在这个组合,那么就可以。
分析及就到此为止了,以下是我Java实现的代码,
package algorithm; public class Remove2s1 { public void WhatLeft(int n){ int total = n*(n+1)/2; int beginNum; if(total%2 == 0){ beginNum = 0; }else{ beginNum = 1; } System.out.println("These numbers maybe left: "); for(;beginNum<=n;beginNum+=2){ if(MaybeLeft(n,beginNum,total)){ System.out.print(beginNum+", "); } } } public boolean MaybeLeft(int n, int num, int total){ int leftTotal = (total-num)/2; int[] numArr = new int[n+1]; for(int i=0; i<=n; i++){ numArr[i] = i; } numArr[num] = 0; int sum = 0; int index = n; while(index>0){ if(sum+numArr[index] == leftTotal){ return true; }else if(sum+numArr[index] < leftTotal){ sum += numArr[index]; } index --; } return false; } public boolean MaybeLeft(int n, int num){ int total = n*(n+1)/2; if(MaybeLeft(n,num,total)){ System.out.println("OK!"); printOrder(n,num,total); return true; }else{ System.out.println("No!"); return false; } } public void printOrder(int n, int num, int total){ int leftTotal = (total-num)/2; int[] numArr = new int[n+1]; for(int i=0; i<=n; i++){ numArr[i] = i; } numArr[num] = 0; int sum = 0; int index = n; System.out.println("Select there numbers:"); while(index>0){ if(sum+numArr[index] == leftTotal){ System.out.print(numArr[index]); break; }else if(sum+numArr[index] < leftTotal){ sum += numArr[index]; if(numArr[index] != 0){ System.out.print(numArr[index]+", "); } } index --; } } public static void main(String args[]){ Remove2s1 rem = new Remove2s1(); rem.WhatLeft(50); rem.MaybeLeft(50,9); } }
运行结果就是1至50,可能剩余的数字
输出结果为:
These numbers maybe left: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, OK! Select there numbers: 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 24
就是1到50之间的奇数都有可能。
或单独查看某个数字是否能留下,一种可能是擦出顺序是,从输出的数字中,依次,从剩余的其他数字中找数字,将该数字抵消掉,直到为0.
例如,n=10,
Remove2s1 rem = new Remove2s1(); rem.WhatLeft(10); rem.MaybeLeft(10,5);
输出:
These numbers maybe left: 1, 3, 5, 7, 9, OK! Select there numbers: 10, 9, 6
要剩余5,可以这样:
1到10: 1、2、3、4、5、6、7、8、9、10
5要剩余,先去掉: 1、2、3、4、6、7、8、9、10
先选10,从1、2、3、4、7、8中选两个数消除掉,就8和2吧,剩下:1、3、4、6、7、9
再选9,从1、3、4、7中,选数字7、1吧,剩余1、3、4、6,
最后选6,将剩余1、3、4,想办法抵消掉,比如6-4=2、3-2=1、1-1=0,到此为止。
相关文章推荐
- <笔试><面试>C/C++单链表(最综合)最全工程从建立到相关函数实现
- <笔试><面试>C/C++单链表相关(4)判断两链表是否相交,求交点(链表不带环/可能带环)
- <笔试><面试>判断一个数是否在40亿个中
- <笔试><面试>单链表相关(1)从尾到头打印链表、删除一个无头链表的非尾结点
- <笔试><面试>编写一个排序函数,实现,既可以排序整形数组,又可以排序字符串。
- <php>只能输入数字的文本框-Php
- <PY><core python programming笔记>C5 数字
- android面试题目大全<完结部分>,android笔试题目集锦
- <input>标签 只输入 数字 int类型
- <Win32_2>Bitmap位图应用1 ------ Win32的数字时钟
- 在黑板上写下50个数字:1至50。在接下来的49轮操作中,每次做如下操作:选取两个黑板上的数字a和b,擦去,在黑板上写|b-a|。请问最后一次动作之后剩下的数字可能是什么?为什么?
- [笔试题]黑板上写下50个数字,选两个黑板上数字a和b,在黑板写|b-a|,剩下的数字?
- <转> 面试java高级工程师、项目经理等的常见问题
- android面试题目大全<完结部分>,android笔试题目集锦
- <kingofark关于学习C++和编程的50个观点> 详解 - 预览版
- <有道笔试题>链表加法的递归实现
- android面试题目大全<完结部分>,android笔试题目集锦
- <<unix 网络编程>> 源码编译daytimetcpcli.c 问题汇总
- <<程序员职场第一课>>读后感
- <c:forEach>标签