C++竞赛经典代码(1)
案例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;
}
