题解:UVA10761 Broken Keyboard

封面

题目传送门

题意:

完整题目:

UVA10761 Broken Keyboard

题目描述

某些键盘上的字母键坏了,但是所有非字母键都功能正常。尽管如此,我们还是需要输入一段文本,并希望知道可以完整输入多少行文本。此外,在我们仍然能够输出相同的文本行的基础上,我们还想知道哪些其他的字母键也可以坏掉。

输入格式

程序应该从名为 keyboard.dat 的文件中读取输入。这个题目有但是不需要。 输入文件包含多个案例。每个案例的第一行列出了一系列坏掉的字母键。接下来的几行是希望输入的文本。此文本以以下行结束:

END

该行也应被处理。输入的任何一行都不会超过80个字符。当输入的第一个单词为 finish 时,表示输入终止,此案例不应被处理。

输出格式

输出应格式化为一个表格,参见样例输出。表头占据4行,如下所示,另有一行用于标记字符位置;这行不是表头的一部分。

12345678901234567890123456789012345678901234567890123456789
+----------+----------------+-----------------------------+
| Keyboard | # of printable | Additionally, the following |
| | lines | letter keys can be broken |
+----------+----------------+-----------------------------+

在表格的剩余行中,对于每个输入案例,你应该输出两行,格式如下:

  • 表格的第一列报告了键盘的编号。键盘从 11 开始顺序编号。这个数字应在第 5577 个字符处右对齐打印。
  • 表格的第二列报告了使用坏掉的键盘可以输入的文本行数。这个数字应在第 19192121 个字符处右对齐打印。每个案例中的文本行数不会超过 999999 行。
  • 表格的第三列报告了哪些额外的字母键可以坏掉,而我们仍然能够输入第二列中报告的行数。额外的字母键应按字母顺序排列,从第 3131 个字符开始打印。
  • 每个案例的第二行输出为一条水平线,如样例输出所示。 表格中使用的唯一空白字符是空格和换行符。

输入输出样例

输入 #1

Xyz
We will work with a basic time unit of an eighth-note. At any
given time, your left foot and right foot will each be on distinct
arrows. Only one foot may perform an action (changing arrows and/or
tapping) during any time unit; jumping is not allowed. Also, you must
remain facing forward in order to see the screen. This puts
limitations on which feet you can use to hit which arrows. Finally,
hitting two arrows in a row with the same foot ("double-tapping") is
exhausting, because you can’t shift your weight onto that
foot. Ideally, you want to alternate feet all the way through a string
of consecutive arrows.
END
life
is
sometimes
tough
END
but
one
must
not
give
up
END
finish

输出 #1

+----------+----------------+-----------------------------+
| Keyboard | # of printable | Additionally, the following |
| | lines | letter keys can be broken |
+----------+----------------+-----------------------------+
| 1 | 4 | jkq |
+----------+----------------+-----------------------------+
| 2 | 1 | abcdjkmnpqrsvwxyz |
+----------+----------------+-----------------------------+
| 3 | 3 | acfhjklmpqrswxyz |
+----------+----------------+-----------------------------+

题目简述:

给定一些不可以打出的字母,然后给出几个字符串,求有几个字符串能够打印和还有哪些字母不能打印时不会影响原来可以打印的字符串。

思路:

模拟,没啥思维。

创建两个标记,一个标记不可以打出的字母,另一个标记需要使用的字符,为了方便,以下称为 bjbjbj2bj2,我的代码里也是这两个名字。

遍历需要输出的字符串,如果在这个字符串里有一个字符是在 bjbj 里被标记过的,那么这个字符串不能输出。

如果就算遍历完后,也没有一个字符是在 bjbj 里被标记过的,那么就说明这个字符串是可以输出的,把这个字符串里的所有字符在 bj2bj2 里标记。

没有在 bjbjbj2bj2 里出现过的字符就是还可以坏掉的字符按键。

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define itn int
#define ull unsigned long long
void ges(){
cout<<"+----------+----------------+-----------------------------+\n";// 这个是格式但是题目 pdf 文件有点问题,直接复制不一样
cout<<"| Keyboard | # of printable | Additionally, the following |\n";// 所以在 udebug 里看数据的正确输出就可以复制格式了
cout<<"| | lines | letter keys can be broken |\n";// 洛谷给出的样例也有点问题
cout<<"+----------+----------------+-----------------------------+\n";// 起码在我写的时候是这样的
return ;
}
string a;
int main(){
// ios::sync_with_stdio(0);
// cin.tie(0),cout.tie(0);
ges();
int count=0,case_num=0;
while(getline(cin,a)){
if(a=="finish")break;
case_num++;
unordered_set<char>bj;// 标记哪些字符坏了
for(int i=0;i<a.size();i++)bj.insert(tolower(a[i]));
count=0;
unordered_set<char>bj2;// 标记哪些字符需要使用
while(getline(cin,a)){
// 不在前面判断 END 是因为题目要求,END 也要处理
bool flag=0;
for(int i=0;i<a.size();i++){
if(bj.count(tolower(a[i]))){
flag=1;break;
}
}
if(!flag){
count++;
for(int i=0;i<a.size();i++)bj2.insert(tolower(a[i]));
}
if(a=="END")break;// 这组数据没了
}
string ans;
for(int i=0;i<26;i++){
char ch=i+'a';
if(!bj.count(ch)&&!bj2.count(ch))ans+=ch;
}
printf("| %3d | %3d | %-27s |\n",case_num,count,ans.c_str());
cout<<"+----------+----------------+-----------------------------+\n";
}
return 0;
}