免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 8115 | 回复: 30
打印 上一主题 下一主题

[算法] 一道上海交大研究生入学考试试题:物以稀为贵 [复制链接]

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-09-11 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-03-13 22:52 |只看该作者 |倒序浏览
本帖最后由 linuxchyu 于 2013-03-15 00:57 编辑

1  2  3   
4  5  6
7  8  9
    0  
说某移动电信运营商开发了一个名为“争霸”的游戏,为鼓励用户参与,凡签约用户均可获得前三位为888的手机号码,但这样的话就有10的8次方种可能,现在给出一种限制条件减少号码数量,就是两个相邻号码之间的关系必须满足象棋里的“将步”
即:给你前三位都是888  后面8位是上面的数字  每个数的相邻只有有限个数字
比如8881*  那么与1相邻的只可以是2和4  
888812那么与2相邻的只可以是1,5,3  就是这个意思(888后面的第一个数字不受将步的限制)
如果选择5  那么可以选择的有2,4,6,8
问:
1  用什么算法比较好?为什么?
2  最优的算法是什么?为什么?
3  用什么数据结构最好?为什么?
4  时间复杂度和空间复杂度?
5  一共有多少种情况?


先确认下哈:答案是14826种。不过这种考试题肯定是要你寻找比较优化的方法。

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
2 [报告]
发表于 2013-03-14 09:29 |只看该作者
这还要什么复杂算法?就一个个遍历呗
从最小的数 (888)08080808 开始
先动个位,个位动不了的话动十位,……,乃至动千万位,还动不了说明结束了

(888)08080852
(888)08080854
(888)08080856
……
(888)98989898

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
3 [报告]
发表于 2013-03-14 09:36 |只看该作者
哦,明白了,主要是求“5  一共有多少种情况?”,而不是要求输出所有手机号码

论坛徽章:
154
2022北京冬奥会纪念版徽章
日期:2015-08-07 17:10:5720周年集字徽章-年
日期:2022-10-26 16:44:2015-16赛季CBA联赛之深圳
日期:2022-11-02 14:02:4515-16赛季CBA联赛之八一
日期:2022-11-28 12:07:4820周年集字徽章-20	
日期:2023-07-19 08:49:4515-16赛季CBA联赛之八一
日期:2023-11-04 19:23:5115-16赛季CBA联赛之广夏
日期:2023-12-13 18:09:34
4 [报告]
发表于 2013-03-14 09:47 |只看该作者
本帖最后由 shang2010 于 2013-03-14 09:49 编辑

树的遍历,这种题蛮费脑汁的,

因为不小心就会有数学方法,套用一个公式直接要答案。。

论坛徽章:
0
5 [报告]
发表于 2013-03-14 09:50 |只看该作者
帮LZ加一个问题 所有号码中 最后一位是0的概率是多少

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
6 [报告]
发表于 2013-03-14 09:52 |只看该作者
递归就行了 47132

论坛徽章:
154
2022北京冬奥会纪念版徽章
日期:2015-08-07 17:10:5720周年集字徽章-年
日期:2022-10-26 16:44:2015-16赛季CBA联赛之深圳
日期:2022-11-02 14:02:4515-16赛季CBA联赛之八一
日期:2022-11-28 12:07:4820周年集字徽章-20	
日期:2023-07-19 08:49:4515-16赛季CBA联赛之八一
日期:2023-11-04 19:23:5115-16赛季CBA联赛之广夏
日期:2023-12-13 18:09:34
7 [报告]
发表于 2013-03-14 09:52 |只看该作者
@hisptoot

你相不相信,高中生都能解

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
8 [报告]
发表于 2013-03-14 09:56 |只看该作者
表输错了, 43038
  1. #!/usr/bin/perl -w

  2. use strict;
  3. use warnings;

  4. my %map = (
  5.     1 => [2, 4],
  6.     2 => [1, 3, 5],
  7.     3 => [2, 6],
  8.     4 => [1, 5, 7],
  9.     5 => [2, 4, 6, 8],
  10.     6 => [3, 5, 9],
  11.     7 => [4, 8],
  12.     8 => [5, 7, 9, 0],
  13.     9 => [6, 8],
  14.     0 => [8],
  15. );

  16. sub solve {
  17.     my($n, $last) = @_;

  18.     if ($n == 1) {
  19.         return map { [ $_ ] } @{$map{$last}};
  20.     } else {
  21.         my @ret = map solve($n-1, $_), @{$map{$last}};
  22.         unshift @$_, $last for @ret;
  23.         @ret
  24.     }
  25. }

  26. print "@$_\n" for map {solve 8, $_} 0 .. 9
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
9 [报告]
发表于 2013-03-14 10:00 |只看该作者
先列递归式
然后动态规划

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
10 [报告]
发表于 2013-03-14 10:46 |只看该作者
我计算出来怎么是 5251 个号码

递归法:
  1. #include <stdio.h>

  2. static const int maps[10][4] = { { 8, -1, -1, -1 } // 0
  3.                                , { 2,  4, -1, -1 } // 1
  4.                                , { 1,  3,  5, -1 } // 2
  5.                                , { 2,  6, -1, -1 } // 3
  6.                                , { 1,  5,  7, -1 } // 4
  7.                                , { 2,  4,  6,  8 } // 5
  8.                                , { 3,  5,  9, -1 } // 6
  9.                                , { 4,  8, -1, -1 } // 7
  10.                                , { 0,  5,  7,  9 } // 8
  11.                                , { 6,  8, -1, -1 } // 9
  12.                                };

  13. int foo( int v, int n )
  14. {
  15.     if( v == -1 )
  16.         return 0 ;
  17.     if( n == 8 )
  18.         return 1;

  19.     return foo( maps[v][0], n+1 )
  20.          + foo( maps[v][1], n+1 )
  21.          + foo( maps[v][2], n+1 )
  22.          + foo( maps[v][3], n+1 );
  23. }

  24. int main()
  25. {
  26.     printf( "%d\n", foo(8,0) );
  27.     return 0;
  28. }
复制代码
遍历法:
  1. #include <stdio.h>

  2. int main()
  3. {
  4.     static const int maps[10][4] = { { 8, -1, -1, -1 } // 0
  5.                                    , { 2,  4, -1, -1 } // 1
  6.                                    , { 1,  3,  5, -1 } // 2
  7.                                    , { 2,  6, -1, -1 } // 3
  8.                                    , { 1,  5,  7, -1 } // 4
  9.                                    , { 2,  4,  6,  8 } // 5
  10.                                    , { 3,  5,  9, -1 } // 6
  11.                                    , { 4,  8, -1, -1 } // 7
  12.                                    , { 0,  5,  7,  9 } // 8
  13.                                    , { 6,  8, -1, -1 } // 9
  14.                                    };
  15.     //             0  1  2  3  4  5  6  7  8
  16.     int num[9] = { 8, 0, 8, 0, 8, 0, 8, 0, 8 };
  17.     size_t count = 1;
  18.     for( size_t i=8; i!=0; --i )
  19.     {
  20.         char cur = num[i];
  21.         char pre = num[i-1];

  22.         for( size_t j=0; j<4; ++j )
  23.         {
  24.             if( maps[pre][j] > cur )
  25.             {
  26.                 cur = maps[pre][j];
  27.                 break;
  28.             }
  29.         }

  30.         if( cur != num[i] )
  31.         {
  32.             num[i] = cur;
  33.             for( ; i<8; ++i )
  34.                 num[i+1] = maps[num[i]][0];
  35.             ++count;

  36.             for( size_t k=0; k<8; ++k )
  37.                 printf( "%d", num[k+1] );
  38.             printf( "\n" );
  39.             
  40.             i = 9;
  41.             continue;
  42.         }
  43.     }

  44.     printf( "%u\n", (unsigned)count );
  45.     return 0;
  46. }
复制代码
我还想用小白说的“动态规划”,不过,代码难写了点,算了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP