试题F:成绩统计
【问题描述】
小蓝给学生们组织了一场考试,卷面总分为 100 分,
每个学生的得分都是一个 0 到 100 的整数。
如果得分至少是 60 分,则称为及格。
如果得分至少为 85 分,则称为优秀。
请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。
【输入格式】
输入的第一行包含一个整数 n,表示考试人数。
接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。
【输出格式】
输出两行,每行一个百分数,分别表示及格率和优秀率。
百分号前的部分四舍五入保留整数。
【样例输入】
7 80 92 56 74 88 100 0
【样例输出】
71% 43%
解题思路:
一道简单的模拟题,第一题细心点好好做,没啥问题。
代码:
#include using namespace std; int main() { int n; cin >> n; double a = 0, b = 0, score; for (int i = 0; i < n; i++) { cin >> score; if (score >= 60) a++; if (score >= 85) b++; } //%.0f能够自动四舍五入 printf("%.0f%% %.0f%%", (a / n) * 100, (b / n) * 100); return 0; }
试题G:回文日期
【问题描述】
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。
因为如果将这个日期按 “yyyymmdd” 的格式写成一个8 位数是20200202,
恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是“千年一遇” 的特殊日子。
对此小明很不认同,因为不到2年之后就是下一个回文日期:20211202 即 2021年12月2日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。
对此小明也不认同:
因为大约100 年后就能遇到下一个ABABBABA 型的回文日期:21211212 即 2121 年12 月12 日
算不上“千年一遇”,顶多算“千年两遇”。
给定一个 8 位数的日期,
请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。
【输入格式】
输入包含一个八位整数N,表示日期。
【输出格式】
输出两行,每行1 个八位数。
第一行表示下一个回文日期,
第二行表示下一个ABABBABA 型的回文日期。
【样例输入】
20200202
【样例输出】
20211202 21211212
【评测用例规模与约定】
对于所有评测用例,10000101 ≤ N ≤ 89991231,保证N 是一个合法日期的8位数表示。
解题思路:
这道题的思路是枚举之后的日期,然后判断他们是否符合题目要求。
根据数据返回,我们需要枚举1000~10000年。
代码:
#include using namespace std; int mon[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //20211202 bool check1(int date) { int year = date / 10000; int month = date / 100 % 100; int day = date % 100; if (month > 12) return false; if (month == 2 && ((year % 4 == 0 && year % 100) || year % 400 == 0) && day > mon[month] + 1) return false; if (month != 2 && day > mon[month]) return false; return true; } //21211212 bool check2(int date) { int year = date / 10000; int month = date / 100 % 100; int day = date % 100; if (month > 12) return false; if (month == 2 && ((year % 4 == 0 && year % 100) || year % 400 == 0) && day > mon[month] + 1) return false; if (month != 2 && day > mon[month]) return false; if (day != month) return false; return true; } int main() { int date1; cin >> date1; bool flag1 = false, flag2 = false; for (int i = 1000; i < 10000; i++) { int date = i, x = i; //将date翻转接上原来的date,就能让该日期变成一个回文串 for (int i = 0; i < 4; i++) { date = date * 10 + x % 10; x /= 10; } //判断翻转之后该日期是否合法(题目第一个要求) if (!flag1 && date > date1 && check1(date)) { flag1 = true; cout << date << endl; } //判断翻转之后该日期是否合法以及是否是 ABABBABA 型 if (!flag2 && date > date1 && check2(date)) { flag2 = true; cout << date << endl; } if (flag1 && flag2) break; } return 0; }
试题H:字串分值
【问题描述】
对于一个字符串 S,我们定义 S 的分值 f (S) 为 S 中出现的不同的字符个数。
例如 f ( ”aba” ) = 2, f ( ”abc” ) = 3, f ( ”aaa” ) = 1。
现在给定一个字符串 S [0..n − 1](长度为 n),
请你计算对于所有 S 的非空子串 S [ i..j ] (0 ≤ i ≤ j < n), f (S [ i..j ]) 的和是多少
【输入格式】
输入一行包含一个由小写字母组成的字符串S。
【输出格式】
输出一个整数表示答案。
【样例输入】
ababc
【样例输出】
28
【样例说明】
子串 f值
a 1
ab 2
aba 2
abab 2
ababc 3
b 1
ba 2
bab 2
babc 3
a 1
ab 2
abc 3
b 1
bc 2
c 1
【评测用例规模与约定】
对于20% 的评测用例,1 ≤ n ≤ 10;
对于40% 的评测用例,1 ≤ n ≤ 100;
对于50% 的评测用例,1 ≤ n ≤ 1000;
对于60% 的评测用例,1 ≤ n ≤ 10000;
对于所有评测用例,1 ≤ n ≤ 100000。
解题思路:
这里我用的思路是利用STL里面,
set的特性,set能够自动帮我们去重,
那我们只需要枚举字符串,然后计数就行了。
代码:
#include #include #include ; using namespace std; int main() { string s; cin >> s; int sum = 0; for (int i = 0; i < s.size(); i++) { set p; for (int j = i; j < s.size(); j++) { p.insert(s[j]); sum += p.size();//去重之后的size就是字母的种类 } } cout << sum << endl; return 0; }
试题I:平面切分
【问题描述】
平面上有 N 条直线,其中第 i 条直线是 y = Ai · x + Bi。
请计算这些直线将平面分成了几个部分。
【输入格式】
第一行包含一个整数 N。
以下 N 行,每行包含两个整数 Ai; Bi。
【输出格式】
一个整数代表答案。
【样例输入】
3 1 1 2 2 3 3
【样例输出】
6
【评测用例规模与约定】
对于 50% 的评测用例, 1 ≤ N ≤ 4, −10 ≤ Ai; Bi ≤ 10。
对于所有评测用例, 1 ≤ N ≤ 1000, −100000 ≤ Ai; Bi ≤ 100000。
解题思路:
数学学渣表示真的做不出来。。。呜呜呜。。。
代码:
代码参考:
#include using namespace std; typedef long long LL; using namespace std; const int N = 100010; string s; int pre[N],ne[N]; int a[27]; int main() { cin >>s; s = "0" + s; //获取字符串长度 int len = s.length(); //有步初始化,我直接声明的全局变量,是可以不用的,为了和后面操作想呼应,就写完整吧 for(int i = 0; i < 27;i++) a[i] = 0; //找前一个相同字符的下标 for(int i = 1; i < len;i++) { //将'a'变成偏移量,获得 int index = s[i] - 'a'; pre[i] = a[index]; a[index] = i; }
for(int i = 0; i < 27;i++) a[i] = len; //找下一个相同字符的下标 for(int i = len - 1; i >= 1;i--) { int index = s[i] - 'a'; ne[i] = a[index]; a[index] = i; } LL ans = 0; for(int i = 1; i ans += (LL)(i - pre[i]) * (ne[i] - i); cout << ans << endl; return 0; }
试题J:字串排序
解题思路:
别看啦,我连上一题都做不出来,
这题当然也做不出来。。。
写在最后:
以上就是本篇文章的内容了,感谢你的阅读。
如果喜欢本文的话,欢迎点赞和评论,写下你的见解。
如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。
之后我还会输出更多高质量内容,欢迎收看。