Day4:P5587 打字练习C++

题目描述

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值