对于开始学习C语言程序设计或C++程序设计面向过程部分的同学来说,利用在线OJ网站进行实践训练,对提高自己的编程能力很有好处。国内外OJ网站很多,每个都去看看,去刷个题,是不现实的,也没必要。即使一个OJ网站,上面3~4千道题也难全部刷完。因此,给大家推荐两个OJ网站。一个是北京大学的PKU JudgeOnline(http://poj.org/ ),简称POJ;另一个是杭州电子科技大学的HDU Online Judge System (http://acm.hdu.edu.cn/),简称 HDU。将这两个网站结合起来用于程序设计的训练是有帮助的。
POJ上面有3千多道题,绝大部分是英文题目,显得高大上些;HDU上有近6千道题,有部分中文题目,比POJ接地气些。这两个OJ网站上的题目编排顺序不是按难易程度,也不是按专题(HDU稍微好些,有时还有些专题集锦的小概念)。因此,对初学者而言,究竟找哪些题刷是个问题。题目难了,无从下手,伤信心和兴趣,老刷简单的,对提高作用就不大了。有时逛网络,又经常发现一些文章这水题一枚,那水题又一枚,自己拿来一看,又不一定是那回事。作为一个程序设计初学者,你就是一小学生,有那么一嘚瑟的大学生跟你讲微积分简单,一元二次方程不值得提,道理一样。别过多在意别人的说法,自己根据自己的水平,找到适合自己做的事就好了。
有鉴于此,我整理了一个随笔专题:致初学者。主要想帮助初学者在POJ和HDU上找到合适的题目训练。大牛们别笑话,路过好了。
我们先看HDU。HDU 题目集第11卷中Pro.ID号为2000~2099这100道题中85%是中文题目,题意理解起来不存在语言障碍。并且这100道题本身被归结为一些小专题,比如2000~2032这33道题就被归结为“C语言程序设计练习(一) ”~“C语言程序设计练习(五) ”,对于初学者作为习题进行训练恰到好处。下面我以题解的形式先给出这100道题的AC程序,供大家参考。
HDU 2000: ASCII码排序
简单的分支选择结构。输入a,b,c三个字母,比较交换a和b,使a比b小;比较交换a和c,使a比c小;这样a就是最小的字母了;最后比较交换b和c,使b比c小。
#include <stdio.h> int main() { char c1,c2,c3,temp; while (scanf("%c%c%c",&c1,&c2,&c3)!=EOF) { if (c1>c2) { temp=c1; c1=c2; c2=temp; } if (c1>c3) { temp=c1; c1=c3; c3=temp; } if (c2>c3) { temp=c2; c2=c3; c3=temp; } printf("%c %c %c ",c1,c2,c3); getchar(); } return 0; }
HDU 2001:计算两点间的距离
简单公式计算。已知两点坐标(x1,y1)和(x2,y2),两点距离公式为sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))。
#include <stdio.h> #include <math.h> int main() { double x1,x2,y1,y2,dis; while (scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2)!=EOF) { dis=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); printf("%.2lf ",dis); } return 0; }
HDU 2002:2002 计算球体积
简单公式计算题。已知半径r,球的体积计算公式为:V=4/3*PI*r3。
#include <stdio.h> #define PI 3.1415927 int main() { double r,v; while (scanf("%lf",&r)!=EOF) { v=4.0/3*PI*r*r*r; printf("%.3lf ",v); } return 0; }
HDU 2003: 求绝对值
简单选择结构 if (x<0) x=-x;
#include <stdio.h> int main() { double x; while (scanf("%lf",&x)!=EOF) { if (x<0) x=-x; printf("%.2lf ",x); } return 0; }
HDU 2004:成绩转换
多分支嵌套 if …else if ……
#include <stdio.h> int main() { int score; while (scanf("%d",&score)!=EOF) { if (score<0 || score>100) printf("Score is error! "); else if (score<60) printf("E "); else if (score<70) printf("D "); else if (score<80) printf("C "); else if (score<90) printf("B "); else printf("A "); } return 0; }
HDU 2005:第几天?
switch …case …结构的灵活使用。
#include <stdio.h> int main() { int year,month,day,d; while (scanf("%d/%d/%d",&year,&month,&day)!=EOF) { d=0; switch(month-1) { case 11:d+=30; case 10:d+=31; case 9:d+=30; case 8:d+=31; case 7:d+=31; case 6:d+=30; case 5:d+=31; case 4:d+=30; case 3:d+=31; case 2:d+=28; if (year%4==0 && year%100!=0 || year%400==0) d++; case 1:d+=31; } d=d+day; printf("%d ",d); } return 0; }
或数组的应用。
#include <stdio.h> int main() { int table[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int year,month,day,d,i; while (scanf("%d/%d/%d",&year,&month,&day)!=EOF) { d=0; for (i=1;i<=month-1;i++) d+=table[i]; if (month>2 && (year%4==0 && year%100!=0 || year%400==0)) d++; d=d+day; printf("%d ",d); } return 0; }
HDU 2006:求奇数的乘积
简单循环结构。
#include <stdio.h> int main() { int n,x,p,i; while (scanf("%d",&n)!=EOF) { p=1; for (i=1;i<=n;i++) { scanf("%d",&x); if (x%2) p*=x; } printf("%d ",p); } return 0; }
HDU 2007:平方和与立方和
简单循环结构。
#include <stdio.h> int main() { int x,y,i,t,sum1,sum2; while (scanf("%d%d",&x,&y)!=EOF) { if (x>y) { t=x; x=y; y=t; } sum1=sum2=0; for (i=x;i<=y;i++) { if (i%2) sum2+=i*i*i; else sum1+=i*i; } printf("%d %d ",sum1,sum2); } return 0; }
HDU 2008:数值统计
循环体中用选择结构分别统计大于0、等于0和小于0的数的个数。
#include <stdio.h> int main() { int n,i,a,b,c; double x; while (scanf("%d",&n) && n!=0) { a=b=c=0; for (i=1;i<=n;i++) { scanf("%lf",&x); if (x>0) c++; else if (x<0) a++; else b++; } printf("%d %d %d ",a,b,c); } return 0; }
HDU 2009:求数列的和
简单循环结构。
#include <stdio.h> #include <math.h> int main() { int n,m,i; double x,sum; while (scanf("%d%d",&n,&m)!=EOF) { x=1.0*n; sum=0.0; for (i=1;i<=m;i++) { sum+=x; x=sqrt(x); } printf("%.2lf ",sum); } return 0; }
HDU 2010:水仙花数
简单循环结构。设a,b,c分别表示3位数x的百位、十位和个位,则
a=x/100 ; b=x%100/10; c=x%10;
#include <stdio.h> #include <math.h> int main() { int n,m,i,a,b,c,cnt; while (scanf("%d%d",&m,&n)!=EOF) { cnt=0; for (i=m;i<=n;i++) { a=i/100; b=i%100/10; c=i%10; if (i==a*a*a+b*b*b+c*c*c) { cnt++; if (cnt!=1) printf(" "); printf("%d",i); } } if (cnt==0) printf("no "); else printf(" "); } return 0; }
HDU 2011:多项式求和
简单循环结构。为进行奇数项相加,偶数项相减的切换。定义变量flag,初始值为1,之后每循环一次后flag=-flag,即 1,-1,1,-1,1,-1,…,从而实现加减的切换。
#include <stdio.h> #include <math.h> int main() { int n,m,i,flag; double sum; scanf("%d",&m); while (m--) { sum=0.0; flag=1; scanf("%d",&n); for (i=1;i<=n;i++) { sum+=flag*1.0/i; flag=-flag; } printf("%.2lf ",sum); } return 0; }
HDU 2012:素数判定
将素数的判定抽象为一个函数。原型为: bool isPrime(int x);
#include <stdio.h> #include <math.h> bool isPrime(int x) { int i,n; n=(int)sqrt(1.0*x); for (i=2;i<=n;i++) if (x%i==0) return false; return true; } int main() { int x,y,i,cnt; while (1) { scanf("%d%d",&x,&y); if (x==0 && y==0) break; cnt=0; for (i=x;i<=y;i++) { if (isPrime(i*i+i+41)) cnt++; } if (cnt==y-x+1) printf("OK "); else printf("Sorry "); } return 0; }
HDU 2013:蟠桃记
简单循环迭代计算。迭代式为 num=2*(num+1); 迭代初值num=1。
#include <stdio.h> int main() { int n,day,num; while (scanf("%d",&n)!=EOF) { num=1; for (day=n-1;day>=1;day--) { num=2*(num+1); } printf("%d ",num); } return 0; }