您的位置:首页 > 职场人生

<笔试面试>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实现的代码,

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,到此为止。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐