开始之前
本人是刚学完C++基础语法的萌新,从B站了解到了杭电的100道水题基础题,于是打算开始刷题并在这里写下解题思路和一些想法,以便日后回顾,顺便分享给大家。我的计划是一天15题。
这是我第一次在CSDN上发文章,还不是很熟悉怎么编辑。
基本上每一题都会把代码和感想放这里。
2000 ASCII码排序
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
char a[3];
while (cin >> a) {
vector<char>v;
v.push_back(a[0]);
v.push_back(a[1]);
v.push_back(a[2]);
sort(v.begin(), v.end());
cout << v[0] << " " << v[1] << " " << v[2] << " " << endl;
}
这里也可以用冒泡排序,但是我学了stl就直接sort偷懒了(好吧其实我两种都写了一遍)。
2001 计算两点间的距离
#include<iostream>
#include <stdlib.h>
using namespace std;
double x1, y1,x2, y2;
while (cin >> x1 >> y1 >> x2 >> y2) {
double distance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
printf("%.2lf\n", distance);
}
写这题的时候学到的新东西:开方函数,以及如何保留几位小数打印数据。(比较好奇为啥这题通过率比上一题低)
2002 计算球体积
#include<iostream>
#include<vector>
#include<algorithm>
#include <stdlib.h>
using namespace std;
double r;
while (cin >> r) {
double v = (4 * 3.1415926535 * r * r * r) / 3;
printf("%.3lf\n", v);
}
记住球的体积公式就好了。我这里应该直接 define 一个PI,直接写3.1415926535有点不是很美观了,而且如果后面有其他代码又得再写一遍,复用率不高。
2003 求绝对值
#include<iostream>
#include<vector>
#include<algorithm>
#include <stdlib.h>
using namespace std;
double n;
while (cin >> n) {
cout << abs(n) << endl;
}
因为我是几个题的代码写在一个cpp文件中的,所以这里看起来会有很多不必要的头文件,实际上它们是其它题的,以后的头文件我就不放出来了,大家自行分辨吧(?)。
2004 成绩转换
int score;
while (cin >> score) {
if (score < 0 || score>100) {
cout << "Score is error!" << endl;
}
else
{
switch (score / 10)
{
case 10:
cout << "A" << endl;
break;
case 9:
cout << "A" << endl;
break;
case 8:
cout << "B" << endl;
break;
case 7:
cout << "C" << endl;
break;
case 6:
cout << "D" << endl;
break;
default:
cout << "E" << endl;
break;
}
}
}
这题我一开始想到是用switch做,运用整数相除所得结果向下取整的特性可以由0~100分得到0~10的整数。中间想到了既然0~59都是E等级那为什么不直接写在default里呢,只要开头加个判断score是否合理就行了,用不着把判断不合理的score写进switch的default中。
2005 第几天?
vector<int>v1 = { 31,28,31,30,31,30,31,31,30,31,30,31 };
vector<int>v2(v1); //v2用以存放闰年的每个月天数
v2[1] = 29;
int year, month, day;
while (scanf_s("%d/%d/%d", &year, &month, &day)) {
int res = 0; //结果
//判断是否为闰年
if (year % 4 == 0) {
for (int i = 0;i < month - 1;i++) {
res += v2[i];
}
res += day;
}
else {
for (int i = 0;i < month - 1;i++) {
res += v1[i];
}
res += day;
}
cout << res << endl;
}
注意遍历的时候 i 最后是 < month - 1 不是 < month 。一开始我还搞错了,发现天数过大。
2006 求奇数的乘积
int size;
while (cin >> size) {
int acc = 1;
for (int i = 0;i < size;i++) {
int num;
cin >> num;
acc = acc * (num % 2 == 0 ? 1 : num);
}
cout << acc << endl;
}
这题的输入格式卡了我好久……一开始还想把用户输入的string中不是空格的元素存入vector<int>中,然后发现又是不会判断空格又是不会char转int,故放弃此方法。其实题目中的“每行的第一个数为n,表示本组数据一共有n个”是在给你提示,告诉你怎么处理这个长度不定的输入。
2007 平方和与立方和
int a, b;
while (cin >> a >> b) {
int sum1 = 0; int sum2 = 0;
for (int i = a; i <= b;i++) {
if (i % 2 == 0) {
sum2 += i * i;
}
else {
sum1 += i * i * i;
}
}
cout << sum2 << " " << sum1 << endl;
}
理解题意有点困难(那个input的两个整数是指区间的两端,一开始理解成了就是那两个数),其他还好,没啥可说的。
2008 数值统计
double n;
while (cin >> n) {
if (n == 0)continue;
int minu_num = 0;
int zero_num = 0;
int posi_num = 0;
for (int i = 0;i < n;i++) {
double num;
cin >> num;
if (num < 0) {
minu_num += 1;
}
else if (num == 0)
{
zero_num += 1;
}
else {
posi_num += 1;
}
}
cout << minu_num << " " << zero_num << " " << posi_num << endl;
}
这里要注意num的类型是double,我一开始写成int是因为思维惯性和没仔细看output示例。
第一行那个n其实还是写成int比较好。
2009 求数列的和
int n, m;
while (cin >> n >> m) {
double sum = 0;
double num = n;
for (int i = 0;i < m;i++) {
sum += num;
num = sqrt(num);
}
printf("%.2lf\n",sum);
}
注意要用一个double类型的数据接收n的值然后反腐对num进行开方,因为n是int类型的数据,开方后还是用int接收的话会丢失信息。(虽然double也会丢失信息,但是咱输出精度只要小数点后两位嘛)
2010 水仙花数
int m,n;
while (cin >> m >> n) {
bool haveNum = false;
for (int i = m;i <= n;i++) {
int units = i % 10;
int tens = (i / 10) % 10;
int hundreds = (i / 100) % 10;
if (i == pow(units, 3) + pow(tens, 3) + pow(hundreds, 3)) {
haveNum = true;
cout << i << " ";
}
}
if (haveNum == false) {
cout << "no";
}
cout << endl;
}
这题没啥可说的,最后记得换行就行。
2011 多项式求和
int n;
while (cin >> n) {
for (int i = 0;i < n;i++) {
int m;
cin >> m;
double res = 0;
for (int j = 1;j <= m;j++) {
res += -(double(1) / j) * pow(-1, j);
}
printf("%.2lf\n", res);
}
}
这题注意一下 1 / j 因为是整数除以整数所以结果也是整数,需要将其中一个数转换成double类型结果才是double.
2006题教会我的输入格式方面的知识在这题又用到了(=^v^=)/
2012 素数判定
bool is_prime(int& num) {
bool b = true;
for (int i = 2;i * i <= num;i++) {
if (num % i == 0) b = false;
}
return b;
}
void Problem_2012() {
int m, n;
while (cin >> m >> n) {
if (m == 0 && n == 0)continue;
bool is_all_prime = true;
for (int i = m;i <= n;i++) {
int res = (i * i) + i + 41;
if (!is_prime(res)) is_all_prime = false;
}
if (is_all_prime) {
cout << "OK" << endl;
}
else {
cout << "Sorry" << endl;
}
}
}
一开始写怎么都是输出OK,最后发现原来是把i写成n了(汗)……
封装函数省内存小技巧:引用传递~
2013 蟠桃记
int n;
while (cin >> n) {
int num = 1;
for (int i = 1;i < n;i++) {
num = (num + 1) * 2;
}
cout << num << endl;
}
2014 青年歌手大奖赛 评委会打分
int n;
while (cin >> n) {
multiset<double>s;
double sum = 0;
for (int i = 0;i < n;i++) {
double num;
cin >> num;
s.insert(num);
sum += num;
}
sum -= *s.begin();
sum -= (*--(s.end()));
double average = sum / (n - 2);
printf("%.2lf\n", average);
}
我第一次写的时候踩坑了,求平均数的时候除以的是n……
目前是第一天,先更新到这里吧。(不知道以后还能不能回来编辑这篇文章)