模拟
题意很清晰,需要我们模拟一下计算正确的单词的个数。对于"<"我们退格处理。正解好像需要用类似栈的数据结构来维护,但并不卡常,直接模拟也可以。
说一下几个注意事项:
1.范文里面有"<",并不是我们需要打上"<",而是删除范文里的内容。(详见代码)
2.对于一整行并且还有空格的输入,我们不能用cin和scanf,因为它们不能读取空格,我们需要用getline 来读取一整行,就像下面这样:
while (getline(cin, a[++n])) { ...... }
3.范文和输入的行数可能并不相等,也就是说范文里面行数可能比输入里面多,不能当成一样的,否则会TLE一个点。
4.防止数组的负下标。
最后献上我丑陋的代码
#include<iostream> #include<cstring> #include<string> #include<cstdio> using namespace std; int n, m , ans, t, siza, sizb; const int N = 1001000; string a[N], b[N]; int siz1[N], siz2[N]; bool pan1[N], pan2[N]; int main() { while (getline(cin, a[++n])) { if (a[n][0] == 'E' && a[n][1] == 'O' && a[n][2] == 'F')break; siz1[n] = a[n].size(); } while (getline(cin, b[++m])) { if (b[m][0] == 'E' && b[m][1] == 'O' && b[m][2] == 'F')break; siz2[m] = b[m].size(); } for (int i = 1; i <= n; ++i) { memset(pan1, 0, sizeof(pan1)); memset(pan2, 0, sizeof(pan2)); siza = a[i].size(); sizb = b[i].size(); if (i == n || i > m)break; for (int j = 0; j < siza; ++j) { if (a[i][j] == '<') { int k = j; pan1[j] = 1; for (; k >= 0; --k)if (!pan1[k])break; if (k >= 0)pan1[k] = 1; } } for (int j = 0; j < sizb; ++j) { if (b[i][j] == '<') { int k = j; pan2[j] = 1; for (; k >= 0; --k)if (!pan2[k])break; if (k >= 0)pan2[k] = 1; } } for (int j = 0, now = 0; j < sizb && now < siza; ++j, ++now) { while (pan1[now] && now < siza)++now; while (pan2[j] && j < sizb)++j; if (now >= siza || j >= sizb)break; if (a[i][now] == b[i][j])++ans; } } cin >> t; printf("%d", (int)((double)ans / ((double)t / 60))); return 0; }