HDU 2000 -- 2007 C语言程序设计练习(一)

本文介绍了使用C语言解决一系列编程问题,包括:字符ASCII码排序,计算两点间距离,求球体积,计算绝对值,成绩转换,日期天数计算,奇数乘积,平方和与立方和。涉及排序算法、数学函数如pow和sqrt,以及字符串处理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2000 ASCII码排序

Problem Description
输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符。

Input
输入数据有多组,每组占一行,有三个字符组成,之间无空格。

Output
对于每组输入数据,输出一行,字符中间用一个空格分开。

Sample Input
qwe
asd
zxc

Sample Output
e q w
a d s
c x z

分析:
主要是比较ASCII码大小,然后进行排序。
由于只有三个数,可以进行简单的比较排序。

2000 代码如下:

#include <stdio.h>
int main()
{
	char a, b, c;
	while(scanf("%c%c%c", &a, &b, &c) != EOF)
	{
		getchar();
		char m;
		if(b > c)
		{
			m = c;
			c = b;
			b = m;
		}
		if(a > b)
		{
			m = b;
			b = a;
			a = m;	
		}
		if(b > c)
		{
			m = c;
			c = b;
			b = m;
		}
		printf("%c %c %c\n", a, b, c);
	} 
	return 0;
}

①排序
三个数排序需要比较三次才能是最终正确的顺序

getchar()
从缓冲区读走一个字符,相当于清除缓冲区

作用:
从标准输入流只读取一个字符(包括空格、回车、tab),读到回车符(’\n’)时退出,键盘输入的字符都存到缓冲区内,一旦键入回车,getchar就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到’\n’。要理解这一点,之所以你输入的一系列字符被依次读出来,是因为循环的作用使得反复利用getchar在缓冲区里读取字符,而不是getchar可以读取多个字符,事实上getchar每次只能读取一个字符。如果需要取消’\n’的影响,可以用getchar()来清除,如:while((c=getchar())!=’\n’),这里getchar();只是取得了’\n’但是并没有赋给任何字符变量,所以不会有影响,相当于清除了这个字符。

一开始忽视了使用 getchar ,以至于输出结果发生一些错位(原因还未知)
如下图:在这里插入图片描述


#include <stdio.h>
 
int main()
{
    char n;
    int i,j;
    char str[3];
    while(scanf("%s",str)!=EOF)
    {
        for(i=0;i<3;i++)//冒泡排序法
        {
            for(j=0;j<3;j++{
                if(str[i]<str[j])
                {
                    n=str[i];
                    str[i]=str[j];
                    str[j]=n;
                }
            }
        }
        printf("%c %c %c\n",str[0],str[1],str[2]);
    }
    return 0;
}

①输入字符串

scanf("%s",str);

②排序

for(i=0;i<3;i++)
        {
            for(j=0;j<3;j++{
                if(str[i]<str[j])
                {
                    n=str[i];
                    str[i]=str[j];
                    str[j]=n;
                }
            }

2001 计算两点间的距离

Problem Description
输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离。

Input
输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2,数据之间用空格隔开。

Output
对于每组输入数据,输出一行,结果保留两位小数。

Sample Input
0 0 0 1
0 1 1 0

Sample Output
1.00
1.41

2001 代码如下

#include <stdio.h>
#include<math.h>
int main()
{
	float x1, y1, x2, y2, distance;
	while(scanf("%f %f %f %f", &x1, &y1, &x2, &y2) != EOF)
	{
		float a, b;
		a = pow(x2-x1, 2);
		b = pow(y2-y1, 2);
		distance = sqrt(a + b);
		printf("%.2f\n", distance);	
	}
	return 0;
}

pow() 计算 x 的 n 次方并返回结果
需要有头函数 #include <math.h>

在C语言的标准头文件math.h中,有库函数pow,声明为
double pow(double x, double n);

该函数适用于以下几种情况:
a. 当n为浮点数类型时,必须使用pow。
b. 当x为浮点数或对结果值精度要求不高时,可以使用pow。

sqrt() 开根号
需要有头函数 #include <math.h>

③浮点数表示
题目中有要求保留两位小数

%.2f  //保留两位小数

④依旧需要循环输入。

2002 计算球体积

Problem Description
根据输入的半径值,计算球的体积。

Input
输入数据有多组,每组占一行,每行包括一个实数,表示球的半径。

Output
输出对应的球的体积,对于每组输入数据,输出一行,计算结果保留三位小数。

Sample Input
1
1.5

Sample Output
4.189
14.137

Hint
#define PI 3.1415927

2002 代码如下

#include <stdio.h>
#define PI 3.1415927

int main()
{
	double r, v;
	while(scanf("%lf", &r) != EOF)
	{
		v = 4 * r*r*r * PI / 3;
		printf("%.3lf\n", v);
	}
	return 0;
}


注意:浮点数要用double表示,若用 float 表示,虽然给的例子结果都对,但是不能通过。

分析:
如果不声明,默认小数为double类型,所以如果要用float的话,必须进行强转。
例如:float a=1.3;会编译报错,正确的写法 float a = (float)1.3;或者float a = 1.3f;(f或F都可以不区分大小写)
注意:float是8位有效数字,第7位数字将会四舍五入

C语言中浮点型一般分为float单精度型、double双精度型、long double长精度型,单精度浮点型小数点后面有效数字为6 ~ 7位和双精度浮点型小数点后面有效数字为15~16位。单精度为32位,双精度为64位,8位为一个字节。

在C语言标准库头文件float.h定义了浮点数小数点后的有效位数 :
//float.h头文件的部分代码
#define DBL_DIG 15 //双精度小数点后15位
#define FLT_DIG 6 //单精度小数点后6位
#define LDBL_DIG 19 //长双精度小数点19

2003 求绝对值

Problem Description
求实数的绝对值。

Input
输入数据有多组,每组占一行,每行包含一个实数。

Output
对于每组输入数据,输出它的绝对值,要求每组数据输出一行,结果保留两位小数。

Sample Input
123
-234.00

Sample Output
123.00
234.00

2003 代码如下

#include <stdio.h>
int main()
{
	double a;
	while(scanf("%lf", &a) != EOF)
	{
		if(a >= 0)
		printf("%.2lf\n", a);
		else
		printf("%.2lf\n", -a);
	}
	return 0;
}


定义时,只能使用 double 类型,使用 float 类型不能通过!
(why?)

2004 成绩转换

Problem Description
输入一个百分制的成绩t,将其转换成对应的等级,具体转换规则如下:
90~100为A;
80~89为B;
70~79为C;
60~69为D;
0~59为E;

Input
输入数据有多组,每组占一行,由一个整数组成。

Output
对于每组输入数据,输出一行。如果输入数据不在0~100范围内,请输出一行:“Score is error!”。

Sample Input
56
67
100
123

Sample Output
E
D
A
Score is error!

2004 代码如下

#include <stdio.h>
int main()
{
	int t;
	while(scanf("%d", &t) != EOF)
	{
		if(t>=90 && t<=100)
		printf("A\n");
		else if(t>=80 && t<=89)
		printf("B\n");
		else if(t>=70 && t<=79)
		printf("C\n");
		else if(t>=60 && t<=69)
		printf("D\n");
		else if(t>=0 && t<=59)
		printf("E\n");
		else
		printf("Score is error!\n");
	}
	return 0;
}

①注意格式(换行符不能少)
第一次很顺利写出,但是提交不能过,有想到是因为最后一行少了“ \n ”,但是没想到真的是因为少了一个换行符!!

2005 第几天?

Problem Description
给定一个日期,输出这个日期是该年的第几天。

Input
输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input,另外,可以向你确保所有的输入数据是合法的。

Output
对于每组输入数据,输出一行,表示该日期是该年的第几天。

Sample Input
1985/1/20
2006/3/12

Sample Output
20
71

分析:
一、
闰年的判定条件是:
1、能被4整除,但不能被100整除的年份都是闰年,如1996年,2004年是闰年;
2、能被100整除,又能被400整除的年份也是闰年。如2000年是闰年。
可以用一个逻辑表达式来表示:

 (year%4==0&&year%100!0) || year%400==0

二、
一开始有想到驯循环相加每个月的天数,但是每个月的天数不定,一一相加太过麻烦,想了好久也没有想出来有啥好办法。
查了一下发现!!

可以把月份的天数当作一个数组,并事先赋值,这样有了数组之后思路着实变得简单起来

2005 代码如下

#include <stdio.h>
int main()
{
	int year, month, day;
	while(scanf("%d/%d/%d", &year, &month, &day) != EOF)
	{
		int x = 0;
		if((year%4==0 && year%100!=0) || year%400==0)
		{
			int months[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
			for(int i=0; i<month-1; i++)
			{
				x = x+months[i];
			}
			printf("%d\n", x+day);
		}
		else
		{
			int months[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
			for(int i=0; i<month-1; i++)
			{
				x = x+months[i];
			}
			printf("%d\n", x+day);
		}
	}
	return 0;
} 

①除法“ / ”、取余“ %

除法运算符“/”。二元运算符,具有左结合性。参与运算的量均为整型时,结果为整型,舍去小数。
如果运算量中有一个为实型,结果为双精度实型。
例如:
5/2=2,1/2=0
5/2.0=2.5

(若两数均为整数,结果也为舍去小数的整数;
若两数中有一个小数,则结果也为小数)

求余运算符“%”,二元运算符,具有左结合性。参与运算的量均为整型。求余运算的结果等于两个数相除后的余数。

例如:
5%2=1,1%2=1

运算符%的左右操作数必须都为int型。

②注意一些细节吧

&忘记加第一次没有运行出来结果;

month 和 months 是两个不同的东西,前者是一个具体的数,后者是一个数组,在定义时要注意;

x的定义位置要注意,否则会造成累加;

在 for 循环中,注意 i 的范围是 < month-1,第一个月时不需要加月份具体的天数。

2006 求奇数的乘积

Problem Description
给你n个整数,求他们中所有奇数的乘积。

Input
输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你可以假设每组数据必定至少存在一个奇数。

Output
输出每组数中的所有奇数的乘积,对于测试实例,输出一行。

Sample Input
3 1 2 3
4 2 3 4 5

Sample Output
3
15

2006 代码如下

#include <stdio.h>
int main()
{
	int m, x;
	while(scanf("%d", &m) != EOF)
	{
		int ans = 1;
		for(int i=0; i<m; i++)
		{
			scanf("%d", &x);
			if(x%2 != 0)
			ans = ans*x;
			
		}
		printf("%d\n", ans);
	}
	return 0;
}

①注意 printf 的位置,以后多注意注意注意,争取试运行都能一遍过!

✌,又是一遍过,一点点开心~~

2007 平方和与立方和

Problem Description
给定一段连续的整数,求出他们中所有偶数的平方和以及所有奇数的立方和。

Input
输入数据包含多组测试实例,每组测试实例包含一行,由两个整数m和n组成。

Output
对于每组输入数据,输出一行,应包括两个整数x和y,分别表示该段连续的整数中所有偶数的平方和以及所有奇数的立方和。
你可以认为32位整数足以保存结果。

Sample Input
1 3
2 5

Sample Output
4 28
20 152

分析:题目中有隐含条件,注意分析!比如 m < n,需要用代码加以约束!!

2007 代码如下

#include <stdio.h>
#include<math.h>
int main()
{
	int m, n;
	while(scanf("%d %d", &m, &n) != EOF)
	{
		int x = 0;
		int y = 0;
		if (m > n)
		{
			int j;
			j = m;
			m = n;
			n = j;
		}
		for(int i=m; i<n+1; i++)
		{
			if(i%2 == 0)
			{
				x = x + pow(i,2);
			}
			else
			{
				y = y + pow(i,3);
			}
		}
		printf("%d %d\n", x, y);
	}
	return 0;
}

①分析隐含范围
一开始按给的例子运算也对,但是最后没有通过,是忽略了 m,n 大小问题,需要再添约束和变换。
如下:

if (m > n)
		{
			int j;
			j = m;
			m = n;
			n = j;
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值