经典基础算法之面试题(系列一)(转)

1. 打靶问题的递归解法

Technorati 标记: 递归算法,字典法,二分法,打靶问题,日期问题,求幂,多项式求值

伦敦奥运会火热进行中,让我们来看个打靶的问题:一个射击运动员打靶,靶一共有10环,求连开10枪打中90环的可能行有多少种?
分析:这是一个典型递归求解问题。假设第10枪打x环,则将问题转换为剩下9枪打90-x环的可能有多少种,x的取值范围为[0, 10],根据加法原理,则:10枪打90环的可能 = 第10枪打0环,剩下9枪打90环的可能 + 第10枪打1环,剩下9枪打89环的可能 + 第10枪打2环,剩下9枪打88环的可能 
+ 第10枪打3环,剩下9枪打87环的可能 + 第10枪打4环,剩下9枪打86环的可能 + 第10枪打5环,剩下9枪打85环的可能 
+ 第10枪打6环,剩下9枪打84环的可能 + 第10枪打7环,剩下9枪打83环的可能 + 第10枪打8环,剩下9枪打82环的可能
+ 第10枪打9环,剩下9枪打81环的可能 + 第10枪打10环,剩下9枪打80环的可能。

                                                                         image

递归的停止条件为:
1. 若环数小于0 或者 剩下的环数大于剩下的枪数乘以10(即剩下每枪打10环用不玩所剩环数),则该递归路径不记入可能情况。
2. 若不满足条件1,且所剩枪数为1,则该递归路径记为1中可能情况。

 1:  #include <stdio.h>2:  3:  int recursion(int count, int score)4:  {5:      if (score < 0 || score > count * 10) {6:          return 0;7:      }8:   9:      if (1 ==  count) {
10:          return 1;
11:      }    
12:   
13:      int i = 0;
14:      int sum = 0;
15:   
16:      for (; i <= 10; ++i) {
17:          sum += recursion(count - 1, score - i);
18:      }
19:   
20:      return sum;
21:  }
22:   
23:  int main()
24:  {
25:      printf("result: %d\n", recursion(10, 90));        
26:      return 0;
27:  }

2. 求多项式的值与求幂的快速算法

2.1 求多项式的值

已知多项式中的系数a0,a1,a2……an及x的值,求f(x)。
image
多项式求值问题可以利用辗转相乘的方式进行计算,根据上面的式子分析,可以将上式转换为: f(x) = ((((an * x) + an-1) * x + an-2) * x  ……. + a1) * x + a0 
有了这个变形,代码自然而然就能写出来了:

 1:  #include <stdio.h>2:  3:  int polynomial(const int *coefficient, int n, int x)4:  {5:      int sum = 0;6:   7:      int i = n - 1;8:      for (; i != 0; --i) {9:          sum = sum * x + coefficient[i];
10:      }
11:   
12:      return sum * x + coefficient[0];
13:  }
14:   
15:  int main()
16:  {
17:      int coeff[5] = {1, 2, 3, 4, 5};
18:      printf("result: %d\n", polynomial(coeff, sizeof(coeff) / sizeof(coeff[0]), 10));
19:      return 0;
20:  }

2.2 求幂的快速算法

求x的p次幂本是简单的问题,可以将x次乘p次就可以了,这里我们当然不是要讨论这种计算方法,这里讨论的是怎样高效计算。
有没有可能减少做乘法的次数呢?让我们来做一个分析,考虑x的6次幂的情况:x * x * x * x * x * x = (x * x * x) * (x * x * x)
等式前面部分需进行6次乘法,后半部分需计算(x * x * x) ,然后乘以上次计算的值即可,共4次乘法。
通过上述分析可知,求x的p次幂可以通过递归折半的方法来减少乘法的次数,循着这个思考,实现就不太困难了。

 1:  #include <stdio.h>2:  3:  /* 统计乘法的次数 */4:  static int multiply_count = 0;5:   6:  /* 求x的p次幂 */7:  int power(int x, int p)8:  {9:      int ret =  0;
10:   
11:      if (1 == p) {
12:          return x;
13:      }
14:   
15:      /* 先计算x的p/2次幂 */
16:  ret = power(x, p >> 1);
17:      ret *= ret;
18:      ++multiply_count;
19:   
20:      /* 若p是奇数,则再乘一次x */
21:  if (0 != p % 2 /* 求模本身是一个耗性能的运算,这里可优化为 p – ((p >> 1) << 1) */) { 
22:          ret *= x;
23:          ++multiply_count;
24:      }    
25:   
26:      return ret;
27:  }
28:   
29:  int main()
30:  {
31:      printf("resulut: %d\n", power(2, 20));    
32:      printf("multiply count: %d\n", multiply_count);
33:      return 0;
34:  }

计算2的20次幂总共进行5次乘法就足够了,而原始的算法需要20次,那么这种算法究竟需要多少次乘法呢?
由于该算法根本思想是折半递归,类似于2分查找,所以乘法的次数为lgp取天花板值这个数量级的(lgp表示以2为底p的对数)。
整型int最多表示2的32次幂,因此最多节省24次乘法,对于现代的计算机,这似乎不是特别重要,但是在以下情况下该算法具有重要价值:
1. 对于需要高频率计算幂的情况;
2. 对于大数高精度计算的情况,如需计算2的10000次幂。
当然了,这也是对递归算法和2分法的巧妙应用,学习其思想吧。

3. 一年中的第n天是几月几号?

和这个问题类似的问题还有:
1. 给定某年某月某日,问这是这年的第多少天?
2. 已知某年的1月1号是星期几,求给定的某年某月某日是星期几?

其实这类问题的共同点在于它们都需要考虑闰年问题,大月小月问题;
首先我们解决闰年问题,根据闰年的定义定义如下宏来判断某年是否是闰年:
#define IS_LEAP(X) (((X) % 400 == 0 || (X) % 100 != 0 && (X) % 4 == 0) ? 1 : 0)

在来看大月小月问题,可以定义如下二维数组,用day_count_of_month[0][12]表示润年情况下每月的天数,用day_count_of_month[1][12]表示非润年情况下每月的天数(这就是传说中的字典法了,就是根据提供的信息查表,类似于查字典,所以叫做字典法):
int day_count_of_month[2][12] = {

                                                {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
                                                {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

                                               };

1:  #include <stdio.h> 2:  3:  #define IS_LEAP(X) (((X) % 400 == 0 || (X) % 100 != 0 && (X) % 4 == 0) ? 1 : 0)4:  int day_count_of_month[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 5:                                   {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; 6:  /* 计算year年的第n天是几月几号 */7:  void convert_to_date(int year, int n) 8:  { 9:      int leap = IS_LEAP(year); 
10:      if(year < 1970 || year > 5000 || n <= 0 || n > 365 + leap) { 
11:          printf("bad year\n"); 
12:      }
13:   
14:      int i = 0; 
15:      for(; n > day_count_of_month[leap][i]; ++i) { 
16:          n -= day_count_of_month[leap][i]; 
17:      } 
18:   
19:      printf("year : %d, month : %d, day : %d\n", year, i + 1, n); 
20:  } 
21:   
22:  int main() 
23:  { 
24:      convert_to_date(2012, 230); 
25:  } 

上面这段代码解决了第一个问题,第二个问题可以转换为类似第一个问题的问题:
先计算给定的某年某月某日到给定已知这天的总天数s=>s%7=>利用模运算结果来推算所求日期的星期情况即可。

 

http://www.cnblogs.com/dskit/archive/2012/08/11/2633736.html

 

转载于:https://www.cnblogs.com/bizhu/archive/2012/08/19/2646325.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461769.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2013年11月份我国网络不良与垃圾短信息分析报告

IDC评述网&#xff08;idcps.com&#xff09;12月17日报道&#xff1a;近日&#xff0c;12321网络不良与垃圾信息举报受理中心最新播报了11月份我国不良与垃圾短信息发送情况。根据报告显示&#xff0c;11月份垃圾邮件发送IP地址与上月大体相同&#xff0c;主要集中在湖北、北京…

SCOM Rule 介绍 [SCOM中文系列之六]

SCOM的Rule主要用来收集数据&#xff0c;我们看到的EventView&#xff0c;PerformanceData&#xff0c;Report所需数据大部分都是通过Rule来收集的。 SCOM Rule的基础结构是触发指定的条件&#xff0c;就执行指定的动作。这个我们通过Rule的属性界面可以看的清楚点&#xff1a;…

init进程的详解

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 内核源码——C语言阶段的start_kernel函数_天糊土的博客-CSDN博客 分析根文件系统中的/linuxrc文件_天糊土的博客-CSDN博客 linux内核sys_mount()分析_kai_ding的博客-CSDN博客_sys_mount…

跟着石头哥哥学cocos2d-x(四)--cocos2dx中的动画以及TexturePacker使用

2019独角兽企业重金招聘Python工程师标准>>> 之前向Andreas Loew申请了一枚TexturePacker注册码&#xff0c;很快都下来了&#xff0c;作为回报我打算还是写一篇关于TexturePacker的使用博客吧&#xff0c;有兴趣的可以在这里申请密钥,http://www.codeandweb.com&am…

头像和Karma汽车

Powered by Zoundry RavenTechnorati : Karma, 头像, 汽车 Del.icio.us : Karma, 头像, 汽车 转载于:https://www.cnblogs.com/bsmagic/archive/2008/08/06/1261858.html

All-In-One Code Framework [一站式示例代码库] 【转】

All-In-One Code Framework [一站式示例代码库]2010 对一站式示例代码库&#xff0c;对奋战在一站式示例代码库上的每一位工程师来说都是不同寻常的一年。 在我们共同努力和开发社区的支持下&#xff0c;该项目从一年前的草根雏形&#xff0c;成长为CodePlex排名前三&#xff0…

Ioc容器Autofac介绍

Autofac是轻量级的开源Ioc容器&#xff0c;在这里可以下载http://code.google.com/p/autofac/。如果你用过其他的Ioc容器&#xff0c;那么学习Autofac使用也会比较容易&#xff0c;下面将通过一些例子来讲解其用法。 先看一个例子&#xff1a; 首先新建一个工程&#xff0c;添加…

用代码实现Sharepoint2010的个人信息的照片上传(2)(原创)

用代码从AD读取照片信息并同步到SharePoint2010的个人照片信息中 前言 上篇我们讲到用代码实现了照片信息同步到SharePoint2010的个人照片信息中&#xff0c;但是做的是从文件夹读取照片信息到SharePoint2010,今天我们要做的从AD的thumbnailPhoto属性中读取照片信息到SharePoin…

HTML5实现Word中文字全环绕图片效果

实现这个功能是当时看见数字报的展示出来的编排方式&#xff0c;就是图片热点&#xff0c;而且下载打开还是PDF的&#xff0c;让我这个WP用户咋个看。想实现Word中的编排方式&#xff0c;也需要浏览器支持Word插件&#xff0c;火狐、谷歌、Opera这些都要另外弄插件&#xff0c;…

Bzoj 2127 happiness 最小割

happiness 题解: 将图转换成最小割. 将割完的图中与S相连的点看做选文科, 与T相连的点看做选理科. flow(s, u) 文科值 flow(u,t) 理科值 假设u 和 v 一起选文科有奖励值z, flow(s,u) z/2 flow(s,v) z/2, flow(u,v) z/2 假设u 和 v 一起选理科有奖励值z, flow(u,t) z/2…

POJ 1149 最大流建图 PIGS

题意&#xff1a; 给出猪圈个数 m 和买家人数 n 然后给出m个猪圈的猪的头数.. 接下来 n 行.. 给出mm a1 a2 .. a(mm) k 例如 2 1 5 3 表示第i1个用户 有mm(2) 个猪圈的钥匙 就是有第 a1(1) 个和第 a2(5) 个猪圈的钥匙..还想要买得k头猪.. 问最多能够卖出多少头.. 思路&#xff…

ARM通识——ARM的7种基本工作模式、37个通用寄存器

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、ARM采用32位架构 ARM约定一个Byte是8 bits&#xff0c;一个Halfword是16 bits (2 byte)&#xff0c;一个Word是32 bits (4 byte)。 大部分ARM core 提供ARM 指令集&#xff08;32 bit&#xff0…

以NFS方式挂载rootfs的设置方法

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 更多详细内容&#xff0c;见Linux中NFS服务器的配置(/etc/export)_天糊土的博客-CSDN博客 网络文件系统&#xff08;NFS&#xff0c;network file system&#xff09;&#xff0c;是一种网络通讯协…

分析根文件系统中的/linuxrc文件(附带busybox的介绍)

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 init进程的详解_天糊土的博客-CSDN博客_init进程 busybox详解_linuxarmsummary的博客-CSDN博客 前言 因为uboot给内核传参的bootargs中有“init/linuxrc”这个项目&#xff0c;而由前面的…

CentOS Linux搭建SVN Server配置详解

PS&#xff1a;今天给开发的同事搭建一个公网的SVN Server&#xff0c;google一下&#xff0c;发现下面这篇最详细&#xff0c;就记录下来&#xff0c;重新排版一下。顺便根据自己的使用经验&#xff0c;补充了几个细节和总结。本文配置是基于CentOS 5.x的&#xff0c;但一样适…

405 Method Not Allowed

当jquery easyui的datagrid插件使用.json文件为数据源&#xff0c;通过非http协议访问【就是直接拖进浏览器查看效果】&#xff0c;能正常加载.json文件并且生成datagrid数据源。但是通过http协议访问示例代码时&#xff0c;无法加载json文件生成datagrid的数据源。 这个是由于…

Eclipse之ANT使用

Ant是Java平台下非常棒的批处理命令执行程序&#xff0c;能非常方便地自动完成编译&#xff0c;测试&#xff0c;打包&#xff0c;部署等等一系列任务&#xff0c;大大提高开发效率。如果你现在还没有开始使用Ant&#xff0c;那就要赶快开始学习使用&#xff0c;使自己的开发水…

idea修改maven项目版本号

1 先安装插件 2 控制台执行命令 mvn build-helper:parse-version versions:set -DnewVersion1.1-SNAPSHOT versions:commit 1.1-SNAPSHOT 为你要修改的版本号 技术交流群&#xff1a; 816227112 有时候命令执行完看不到改变&#xff0c;需要刷新下。 转载于:https://www.cnblo…

几个国外开源CMS系统比较

CMS是Content Management System的缩写&#xff0c;意为"内容管理系统"。上一下度娘或者放一下Google&#xff0c;全球的CMS系统&#xff0c;不下千个&#xff0c;开源的不下百个&#xff0c;如果只是普通用户&#xff0c;很难有时间和精力去比较那么多的系统优劣。不…

javascript函数,值得参考!

2019独角兽企业重金招聘Python工程师标准>>> javascript函数一共可分为五类&#xff1a;   常规函数   数组函数   日期函数   数学函数   字符串函数   1.常规函数   javascript常规函数包括以下9个函数&#xff1a;   (1)alert函数&#xff1a;显…