• 阿里2014年9月笔试中的一个算法设计题--擦黑板剩余数字


    5、在黑板上写下50个数字:1至50.在接下来的49轮操作中,每次做如下动作:选取两个黑板上的数字a和b,擦去,在黑板上写|b - a|。请问最后一次动作之后剩下数字可能是什么?为什么?

    题目参见:擦黑板剩余数字

    当时写这道题目的时候并没有明显的思路,后来感觉应该用归纳法进行分析,但还没有理出来一个思路,程序写出来测试了下,3000次测试结果,剩下的都是奇数。

    即,可能生下从1-50范围内的任意奇数

    代码如下:

     1             HashSet<int> hsr = new HashSet<int>();
     2             int[] result;
     3             int flag = 3000;
     4             int count = flag;
     5             string inStr;
     6             int inNum;
     7             Console.WriteLine("请输入试验次数:");
     8             inStr=Console.ReadLine();
     9             if (int.TryParse(inStr,out inNum))
    10             {
    11                 flag= flag > inNum ? flag : inNum;
    12                 count = flag;
    13                 while (flag > 0)
    14                 {
    15                     ArrayList hs = new ArrayList();
    16                     for (int i = 1; i <= 50; i++)
    17                     {
    18                         hs.Add(i);
    19                     }
    20                     int hsCount;
    21                     Random rand = new Random();
    22                     for (int j = 0; j < 49; j++)
    23                     {
    24                         int r1, r2, delta;
    25                         int e1, e2;
    26 
    27                         hsCount = hs.Count;
    28                         r1 = rand.Next(0, hsCount);
    29                         e1 = (int)hs[r1];
    30                         hs.RemoveAt(r1);
    31                         hsCount = hs.Count;
    32                         r2 = rand.Next(0, hsCount);
    33                         e2 = (int)hs[r2];
    34                         hs.RemoveAt(r2);
    35                         delta = Math.Abs(e2 - e1);
    36                         hs.Add(delta);
    37                     }
    38                     if (hs.Count > 0)
    39                     {
    40                         Console.Write("第{0:d3}次试验:", flag);
    41                         foreach (int e in hs)
    42                         {
    43                             Console.Write("{0:d2}", e);
    44                             if (!hsr.Contains(e))
    45                             {
    46                                 hsr.Add(e);
    47                             }
    48                         }
    49                     }
    50                     flag -= 1;
    51                     Thread.Sleep(10);
    52                     Console.WriteLine();
    53                 }
    54                 result = (int[])hsr.ToArray();
    55                 Array.Sort(result);
    56                 Console.WriteLine("{0:d4}次试验结果:", count);
    57                 for (int k = 0; k < result.Length; k++)
    58                 {
    59                     if (!k.Equals(result.Length - 1))
    60                     {
    61                         Console.Write("{0:d2},", result[k]);
    62                     }
    63                     else
    64                     {
    65                         Console.Write("{0:d2}", result[k]);
    66                     }
    67                 }
    68             }
    69             else
    70             {
    71                 Console.WriteLine("请输入正确的整数!");
    72                 Environment.Exit(0);
    73             }    

    该为结果找个有说服力的理论~~~

    update(@2013-11-1)偶尔看到恩格尔的《解决问题的策略》(参考链接),刚翻几页就看到这个题目了,解释很简单,使用的是“不变量原理“。更一般的表述如下:

    正整数n是奇数,在黑板上写下来1-2n,然后任意取两个数a,b,擦去这两个数并写上|a-b|,证明:最后留下的是一个奇数。

    解:设S为黑板上所有数字的和,开始时S=n(2n+1),是个奇数,每一步使S减少2min(a,b),它是个偶数,所以S的奇偶性是个不变量,在整个简化过程中总有S≡1(mod 2),所以最后结果是个奇数。

    作者:RonaldHan
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    shell脚本快速配置yum源
    RAID 5+1
    RAID 10
    TFTP
    CentOS7 初始化脚本 2.0
    CentOS7 初始化脚本 1.0
    Tomcat CGI 轻松打造 Web 服务
    Python 变量类型 —— type() 函数和 isinstance() 函数
    Python源码换行
    RFC 文档搜索与阅读
  • 原文地址:https://www.cnblogs.com/ronaldhan/p/3343975.html
Copyright © 2020-2023  润新知