C++竞赛经典代码(1)

作者: qiqi 分类: 经典案例 发布时间: 2024-08-17 20:10

案例1 设置输出精确度
题目描述
已知圆周率是3.1415926。请在控制台输出圆周率,小数点之后保留3位小数,需要四舍五入。

解析:格式化输出数据最好的方法(没有之一)就是使用printf()函数。printf()函数在输出数据时会自动进行“四舍五入”。

参考代码:

int main()
{
	double pi = 3.1415926;
	printf("%.1f\n", pi);
	return 0;
}

printf()函数的功能十分强大,比如要输出这样的数据: 3.14(注意3.14之前有一个空格)。整个数据占了5个字符的位置,其中小数部分占了2位,小数点占了1位,整数部分占了1位,一共使用了4位,剩下1位用空格补上。那么这时候该怎么用printf()函数来写呢?代码如下:
printf(“%5.2f\n”, pi);

案例2 输出整数部分
题目描述
输入一个双精度浮点数(类型为double),然后输出这个数的整数部分(需四舍五入)。

解析:因为涉及四舍五入的问题,所有大多数同学首先想到的是使用printf()函数。这种方法有个问题,就是无法把整数部分保存起来留给以后使用。如果把浮点型数据赋值给一个整型变量,虽然可以截断小数部分,但是不会“四舍五入”。那该如何确定小数点后最后一位是大于等于5还是小于5呢?最简单的办法就是在数据上再加0.5。如果输入数据的小数点后第一位的数字是大于等于5的话就会进位,如果是小于4的话就不会进位。下面通师给出这两种方法。

参考代码:

int main()
{
double f;
int a;
cin >> f;

//第一种方法,用printf()直接输出
printf("%.0f\n", f);

//第二种方法,通过数据截断来取整数
a = f + 0.5;
printf("%d\n", a);
return 0;
}

讲到这里,请思考一个问题,如果给你一个浮点型数据,让你四舍五入保留小数点后2位。这里并不是让你直接用printf()函数直接输出,而是要把数据保存在另外一个变量中。一个大概的思路是:首先把原来的数据乘上100,然后要保留的小数部分全都变成整数;然后加上0.5,处理四舍五入的问题;在把这个数据赋值给另外一个整数,截断小数部分;最后再把这个数据除以100,恢复原来的大小。参考代码如下:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	double f, res;
	int a;
	cin >> f;

	a = f * 100 + 0.5;
	res = a / 100.0;
	cout << res << endl;

	return 0;
}

案例3 输出小数部分
题目描述
输入一个双精度浮点数(类型为double),然后输出这个数的小数部分。

解析:任何一个实数都可以写成整数+小数的形式。比如3.14可以看成是“整数3加上小数0.14的和”。整数部分可以通过“数据截断获得”,那么小数部分就从实数中减去整数部分就可以得到了。

参考代码:

int main()
{
	double f, b;
	int a;
	cin >> f;

	a = f;	//获得实数的整数部分
	b = f - a; //计算小数部分
	cout << b << endl;

	return 0;
}

案例4 倒水问题
题目描述
小明家经常来客人,于是小明准备了一个大桶和若干个水杯。现在小明想知道,如果把所有的大桶里面的水都倒进杯子里(每一杯都是满的),那么最后一杯里是不是满的,如果不是满的,那么最后一杯水是多少。你能帮他算一下吗?
输入两个整数,分别代表大桶的容积和水杯的容积。输出两个整数,第一个是能倒满杯子的数量,第二个是最后一杯水的量(如果正好装满全部水杯,那么输出零)。

解析:这是一个商和余数的问题。如果大桶的容量是水杯容量的整数倍,那么就不会有余数,或者说余数是零。

参考代码:

int main()
{
	int dt, bz;
	int a, b;
	cin >> dt >> bz;

	a = dt / bz;
	b = dt % bz;

	printf("%d %d\n", a, b);
	return 0;
}

案例5 两数交换
题目描述
输入两个整数到变量a和b中,交换两个变量的值以后再输出。
解析:交换两个变量的方法有很多种:第一种,引入一个临时变量,然后交换;第二种,用加减来交换,第三种用异或运算来交换变量。

参考代码:

int main()
{
	int a, b, t;
	cin >> a >> b;

	//第一种方法
	t = a, a = b, b = t;//收尾相连
	printf("%d %d\n", a, b);

	//第二种方法
	a = a + b;
	b = a - b;
	a = a - b;
	printf("%d %d\n", a, b);

	//第三种方法
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("%d %d\n", a, b);


	return 0;
}

案例6 判断奇偶
题目描述
输入一个整数,如果是偶数输出”yes”,否则输出”no”。
解析:从十进制数的角度来看,偶数除以2的余数是0,奇数除以2的余数是1;而从二进制的角度看,偶数二进制的最低为是0,奇数的最低位是1。无论那种方法都可以判断奇偶。

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int a;
	bool flag = true;//true-偶数;false-奇数

	cin >> a;


	//第一种方法
	if (a % 2 == 1)
		flag = false;

	//第二种方法
	if (a & 1)
		flag = false;

	if (flag)
		cout << "yes";
	else
		cout << "no";
	cout << endl;
	return 0;
}

这里需要注意的是,第一种方法只能针对非负数来判断奇偶。如果是负数的话就会出现错误。比如判断-3,第一种方法也会输出yes。第二种方法对负数的情况也是适用的。

案例7 判断一个数是否是水仙花数
题目描述
输入一个三位数n,判断是否为水仙花数,如果是则输出“YES”,不是则输出“NO”。水仙花数:是指一个3位数,它的每个位上的数字的3次幂之和等于它本身。(例如:1 * 1 * 1 + 5 * 5 * 5 + 3 * 3 * 3 = 153)
解析:此题关键是如何获取整数各个位上的数。参考代码中给出了个位、十位、百位数字的求法,其他位上数字求法以此类推。

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n, gw, sw, bw;
	bool flag = true;//true-是水仙花数;false-不是水仙花数

	cin >> n;

	gw = n / 1 % 10;
	sw = n / 10 % 10;
	bw = n / 100 % 10;

	if (gw * gw * gw + sw * sw * sw + bw * bw * bw != n)
		flag = false;

	if (flag)
		cout << "yes";
	else
		cout << "no";
	cout << endl;
	return 0;
}

案例8 判断字符是数字还是大小写字母
题目描述
输入一个字符,如果是0-9的字符则输出1,如果是小写字母就输出2,如果是大写字母就输出3,其它字母输出0。
解析:数字和字母字符的ASCII都是连续的,顺序和字母表也是一样的。

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	char ch;
	int flag = 0;
	cin >> ch;

	if (ch >= '0' && ch <= '9')
		flag = 1;
	else if ((ch >= 'a' && ch <= 'z'))
		flag = 2;
	else if ((ch >= 'A' && ch <= 'Z'))
		flag = 3;

	cout << flag << endl;
	return 0;
}

案例9 小写字母转大写字母
题目描述
输入一个小写字母,输出对应的大写字母。
解析:小写字母a的ASCII是97,大写字母A的ASCII是65,相差了32。其它小写字母和对应的大写字母也都相差32。因此小写字母转大写字母就是用原来的ASCII值减去32;同理,大写字母转小写字母就是用原来的ASCII值加上32。如果记不住32,只要记住’a’ – ‘A’的值就是要减去的值也可以。同时还要记住的常用ASCII值有字符’0’的ASCII是48,空格的ASCII是32。

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	char ch;
	cin >> ch;
	ch -= 32;  //等价:ch = ch -32;
	//ch -= 'a' - 'A'; 

	cout << ch << endl;
	return 0;
}

案例10 输出后面第n个字符
题目描述
输入一个字符和一个整数n,输出这个字符后得第n个字符。例如输入A 1,输出B。
解析:字符型的常量或变量在计算机中是以ASCII的形式来保存的,以你字符型的常/变量是可以参与算数运算的。同理也可以用ASCII来直接给字符型变量来赋值。比如ch = ‘A’;等价与 ch = 65;

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	char ch, ch2;
	int n;
	cin >> ch >> n;

	ch2 = ch + n;

	cout << ch2 << endl;
	return 0;
}

案例11 两数差
题目描述
输入一个四位数,输出倒序后的新数与原数的差值(结果要求为正数)。 例如输入1234,输出:4321-1234=3087。
解析:要理解位权的概念。456就是4*10^2 + 5* 10^1 +6*10^0的和。10即十进制;0,1,2,…是位权,4,5,6,…是数码。掌握好这些概念,为以后学好二进制、八进制、十六进制的内容奠定基础。

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n, m, gw, sw, bw, qw, t;
	cin >> n;
	gw = n / 1 % 10;
	sw = n / 10 % 10;
	bw = n / 100 % 10;
	qw = n / 1000 % 10;
	m = qw * 1 + bw * 10 + sw * 100 + gw * 1000;
	if (m > n)
	{
		t = m ;
		m = n;
		n = t;
	}
	cout << n << "-" << m << "=" << n - m;
	return 0;
}

案例12 每月天数
题目描述
输入两个整数,分别代表年份和月份,输出该月有多少天。
解析:本题主要是要知道如何判断闰年,闰年的判断有两个条件,只需满足一个即可:1.能够被4整除但不能被100整除的为闰年;2.能够被400整除的为闰年。常规的做法可以使用if…else if…else结构来判断当月的天数,本题可以使用switch()结构来做,程序会更简洁。

参考代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int y, m, days;
	int r;//闰年为1,平年为0
	cin >> y >> m;

	switch (m)
	{
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			days = 31;
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			days = 30;
			break;
	}

	if (m == 2)
	{
		r = ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0);
		days = 28 + r;
	}
	cout << days << endl;
	return 0;
}
这里最后的if语句,功能是判断2月份的天数是28天还是29天。这部分也可以放到switch结构的default中。
#include <bits/stdc++.h>
using namespace std;

int main()
{
	int y, m, days;
	int r;//闰年为1,平年为0
	cin >> y >> m;

	switch (m)
	{
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			days = 31;
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			days = 30;
			break;
		default:
			r = ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0);
			days = 28 + r;
	}

	cout << days << endl;
	return 0;
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

标签云