{算法竞赛入门经典}第一章 程序设计入门

来源:互联网 发布:明朝资本主义萌芽知乎 编辑:程序博客网 时间:2024/04/29 02:34

 

一. 概述

 

      第一章介绍的内容都是相对比较基础的入门级的知识.虽然基础,但是仍然有很多小细节需要多加留心,不然有些错误会让你不知所措..

      本章总体来说是通过一些简明的例题引入编写正规并且完整的程序的必须的知识点.包括输入,输出,以及竞赛时的一些小细节.

 

 

 

 

二. printf()的输出格式

 

      关于printf的各种输出格式以及相应规范条件在各种专业书籍和资料上都有详细的解释说明.这里就不再累述.这里主要讲讲书上提到的几种输出格式.

 

     对于整数和浮点数对应有2种常用的输出格式,分别是 %d 和 %lf.

 

     i) 整数的 %d 格式

        对于整数的输入输出,都用 %d 就可以满足要求,但是如果要一些比较特殊的输出格式时就需要增加一点修饰.比如书上例题1-2中提到的将520反转输出,那么第一位就是0.但是按照普通的%d来输出,首位是0是会被省略掉的(可以上机实验).这时我们可以通过一些修饰来改变这种输出,就是使用 %0md.其中m表示要输出的变量的位数.0表示空位填充0.因此,若使用%05d来输出520的反转数,就是00025.

 

 

     ii) 浮点数的 %lf 格式

        对于浮点数的输出,默认是使用 %lf.实际上,有个更加广泛通用的格式 %.xlf(注意百分号后面有个小数点).

        %.xlf中的x表示的是精确到小数点后几位.很显然,在许多需要精度控制的题目中是很有用的.而 %lf 只不过一种特殊形式,默认的是输出小数点后6位小数,即精确到小数点后6位.  由此,我们可以理解为 %lf = %.6lf

 

     iii)输入 %d 格式, 输出 %lf 格式

         当某变量x以 %d 的格式由scanf输入,无论x是int型还是float型,只要不采用 %d 输出,而采用  %lf 输出,结果会是0.000000.

         所以在使用的时候一定要注意,要么一开始输入就采用 %f 输入 ,要么输出用 %d ,才能使结果正常.

         换句话说,就是要输入输出格式保持一致.

 

     iv)其他

         在书中1.5.1的数据类型实验中,我们可以通过实验看过很多"不正常"或是"不可预料"的输出.

 

         如, 实验A1. 5个1时,程序运行正常,当为6个1和9个1时,编译器给出警告,程序结果不正确.

 

              实验A2. 运行正常.

 

              实验A3.  用 %d 输出为0,用 %lf 输出为 -1.#ND00 .计算结果不报错.

 

              实验A4.  用 %lf 输出 1.0/0.0 为1.#INF00. 用 %d 输出为0 . 

                           用 %lf 输出 0.0/0.0 为1.#IND00. 用 %d 输出为0.

 

              实验A5. 无论用 %d 还是 %lf 计算1/0.系统都会报错.

 

 

 

 

 

 

 

三.程序输出格式

 

    程序输出格式是否规范是算法竞赛中一个重要的评分点.而我们原来在初学编程时的一些"良好的陋习"的这里就需要改变了.由于算法竞赛中对程序结果输出的格式要求很严格,必须完全按照规定来输出.一些基本的输出规范有:

 

    i)  不要为了"界面友好"而自己添加提示信息,如"please input a,b,c:".

 

    ii)  不要使用类似于getch(), system("pause"),等所谓的"辅助函数",这将会影响程序执行的正常流程.

 

    iii)  每行输出均应以回车符结束.这个习惯是我原来不曾有的,即在每个printf的最后加上/n.

 

 

 

 

 

 

 

 

四.习题与例题

 

实验A1

 

 

#include<stdio.h>

int main()

{

   printf("%d",111111111*111111111);

   return 0;

}

 

 

/*

结果:当为5个1的时候,程序正常运行.当为6个1,9个1的时候,编译器警告溢出.程序

     结果不正确.

*/

 

 实验A2

 

 #include<stdio.h>

 int main()

 {

   printf("%lf",111111111.0*111111111.0);

   return 0;

 }

 

 

 /*

 结果:当将运算的数据类型换为浮点数,且输出格式为%lf后,程序结果正常. 

 */

 

实验A3 & A4 & A5

 

 

 #include<stdio.h>

 #include<math.h>

 int main()

 {

   printf("%d",1/0);

   return 0;

 }

 

 

 

 

 /*

  结果:  用%d输出sqrt(-10)的值是0.用%lf输出时为-1.#1ND00.系统不报错 

         用%d输出1.0/0.0的值为0,用%lf输出时为1.#INF00.系统不报错

         用%d输出0.0/0.0的值为0,用%lf输出时为1.#IND00.系统不报错

          无论是用%d还是用%lf输出1/0,程序都不能正常运行,系统报错. 

 */ 

 

实验B1 & B2 & B3 & B4

 

#include<stdio.h> 

int main()

{

  int a,b;

  scanf("%d%d",&a,&b);

  printf("%d %d/n",a,b);

  return 0;

 

 

 

/* 

 结果: B1,B2,B3的结果可以预料.

       当输入为12  s时,结果是12 4199256

  但是当只输入一个s,然后回车时,将不会提示输入下一个数据,直接出结果:

  2147344384  4199256 

*/ 

 

 

实验C1 & C2 & C3 & C4

 

#include<stdio.h>

int main()

{

  printf("%d  %d  %%d //n",1+2,3+4);

  return 0;

 

}

 

 

/*

 结果: 要输出百分号        %% 

       要输出/n            //n 

*/ 

 

 

实践问题1

 

/*

#include<stdio.h>

#include<math.h>

int main()

{

  int a;

  a = pow(2,31);

//double a = pow(2,31);

//printf("%lf/n",a); 

  printf("%d/n",a);

  return 0;

}

*/

 

/*

结果分析: 上面的代码运行结果是2147483647.但是这个结果并不准确,因为2的31次方

          一定是偶数,如果换成double a = pow(2,31);然后用格式%lf输出,则输出

 正确结果2147483648.

 通过加1,减1测试,确定范围是:2147483647~-2147483648. 

 

*/ 

 

/*实验问题4*/

 

#include<stdio.h>

int main()

{

  int a,b,c;

  a = 0;

  b = 0;       //这里b的取值无论是0还是1都能分辨出正确的优先级. 

  c = 1;

  printf("%d",a&&b||c);

  return 0;

}

 

/*

结果分析: 只需要取一组值a,b,c.使得2种顺序的结果不相同即可.

          这里取的a=0,b=0,c=1.若(a&&b)||c 则结果应该是1.

 若是a&&(b||c) 则结果应该是0.

 运行程序,结果为1.故应该是(a&&b)||c这种顺序. 

 

*/

 

 

习题1-1

 

#include<stdio.h>

int main()

{

  int a,b,c;

  scanf("%d%d%d",&a,&b,&c);

  printf("%.3lf/n",(a+b+c)/3.0);

  printf("%3d",(a+b+c)/3); 

  return 0;

}

 

 

//注意表达式是  (a+b+c)/3.0

//若表达式是(a+b+c)/3 就算使用格式符%.3lf输出,结果仍然是0.000.原因见上文分析.

 

 

习题1-4

 

#include<stdio.h>

#include<math.h> 

int main()

{

  int n;

  scanf("%d",&n);

  printf("%lf/n",M_PI);

  printf("%lf  %lf/n",sin(n/180.0*M_PI),cos(n/180.0*M_PI));

  return 0;

}

 

//sin()函数参数是弧度,而不是角度,若要从弧度转化为角度.需要用上面表达式

//n/180.0*M_PI   其中M_PI是常数(实际上是math.h里面定义的一个宏,宏值是圆周率的一个近似值.可以通过右击鼠标->跳至定义查看) 

其他习题都没有什么难度,就不贴了.

五.小结
   总的来说,第一章虽然都是介绍一些比较基础的知识,但是很多细节的处理方面仍需要引起重视.扎实的编程功底是在无数细微的积累中培养出来的.并且,1.5.4这节所提出的实践能力也是十分重要的.这些基本技能是贯彻到整个编程学习和实践中的.希望自己能过踏踏实实地做好,不断总结,提高.
   文中若有错误或者不清晰的地方,望指出..

 

原创粉丝点击