题目描述
R 君在练习打字。
有这样一个打字练习网站,给定一个范文和输入框,会根据你的输入计算准确率和打字速度。可以输入的字符有小写字母、空格和 .
(英文句号),输入字符后,光标也会跟着移动。
输入的文本有多行,R 君可以通过换行键来换行,换行后光标移动到下一行的开头。
R 君也可以按退格键(为了方便,退格键用 <
表示),以删除上一个打的字符,并将光标回移一格。特殊的,如果此时光标已经在一行的开头,则不能继续退格(即忽略此时输入的退格键)。
网站的比较方式遵循以下两个原则:
- 逐行比较,即对于范文和输入的每一行依次比较,不同行之间不会产生影响,多余的行会被忽略。
- 逐位比较,即对于两行的每一个字符依次比较,当且仅当字符相同时才会被算作一次正确,否则会被算作错误。计算答案时,只统计相同的字符个数。
需要注意的是,回车键(换行)不会被计入正确的字符个数。
R 君看到网站上显示他花了 T 秒完成了这次的打字游戏,请你计算出他的 KPM(Keys per minutes,每分钟输入的字符个数),答案四舍五入保留整数部分。
输入格式
R 君会依次告诉你网站的范文,他的输入和花费的时间。
其中范文和输入将会这样读入:给定若干行字符串,以单独的一行 EOF
结束,其中 EOF
不算入输入的文本。
最后一行一个整数 T,表示他打字花费了 T 秒。
可以参考样例输入输出文件和样例解释辅助理解。
输出格式
一行一个整数,表示 KPM。
输入输出样例
代码实现:
注意!!!!
(1) 所给范文中也含有退格符,所以也要对范文进行处理
(2)可能同时存在多个连续的退格符。例如y<x<<<<<x,如果此时光标已经在一行的开头,则不能继续退格(即忽略此时输入的退格键)
(3)溢出问题,进行逐行对比时,范围应该是min(范文行数,打字的行数);进行逐字对比时,范围应该是min(范文某行字符数,打字的某行字符数)。
#include <bits/stdc++.h>
using namespace std;
string f(string a) {//对退格符进行处理
for (int i = 0; i < a.length(); i++) {
if (i == 0 && a[i] == '<') {
a.erase(i, 1);
i--;
}
if (a[i] == '<' && a[i - 1] != '<') {
a.erase(i - 1, 2);
i = i - 2;
}
}
return a;
}
int main() {
string cor[10010];
string item;
getline(cin, item);
int num1 = 0;
while (item != "EOF") {
cor[num1] = f(item);//范文中也有退格符
getline(cin, item);
num1++;
}
string text[10010];
int num2 = 0;
getline(cin, item);
while (item != "EOF") {
text[num2] = f(item);
getline(cin, item);
num2++;
}
int count = 0;
for (int i = 0; i < min(num1, num2); i++) {//注意min()操作:避免溢出
for (int j = 0; j < min(cor[i].length(), text[i].length()); j++) {
if (cor[i][j] == text[i][j]) {
count++;
}
}
}
double t;//打字时间(单位:秒)
cin >> t;
cout << round(count * 1.0 / t * 60.0); //对浮点数进行四舍五入
return 0;
}
使用栈的思想去解决退格符问题:
(1)当输入的字符为退格符“<"时,且栈不为空,弹出栈顶元素;
(2)当时输入的字符不为退格符时,将该字符压入栈中。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int main() {
string correct[N] = {}, text[N] = {};
string s;
int num1 = 0, num2 = 0;
while (getline(cin, s), s != "EOF") { //范文处理
for (int i = 0; i < s.length(); i++) {
if (s[i] == '<' && !correct[num1].empty()) {
correct[num1].pop_back();
} else if (s[i] != '<') {
correct[num1].push_back(s[i]);
}
}
num1++;
}
while (getline(cin, s), s != "EOF") { //打字处理
for (int i = 0; i < s.length(); i++) {
if (s[i] == '<' && !text[num2].empty()) {
text[num2].pop_back();
} else if (s[i] != '<') {
text[num2].push_back(s[i]);
}
}
num2++;
}
//进行对比
int num = 0;
for (int i = 0; i < min(num1, num2); i++) {
for (int j = 0; j < min(correct[i].length(), text[i].length()); j++)
if (correct[i][j] == text[i][j]) {
num++;
}
}
double t;
cin >> t;
cout << round(num * 1.0 / t * 60.0);
return 0;
}