Windows 下的换行符号是 "\r\n" , 这一段代码会错是因为读完字母后会先读到'\r',退出循环。第二次进入时又再读一次读到'\n',直接退出。用了四次,最后只读第一行和第二行放在第一个和第三个变量里。
void read(ull s[]) {
char ch = getchar(); ull x = 0;
while (ch != '\r' && ch != '\n') {
++x; s[x] = 0;
while (ch<'a'||ch>'z') ch=getchar();
while (ch>='a'&&ch<='z') s[x]=s[x]*P+ch-'a'+1, ch=getchar();
}
s[0] = x;
}
如果只用 '\r' 判断结尾就可以通过洛谷,第二个 while() 会筛去 '\n'。有一些更老的统换行是 '\r' ,Linux 的换行只有 '\n',改完后过不了 Linux,为了保险,写成:
void read(int s[]) {
char ch; int x = 0;
do {
++x;
while (ch<'a'||ch>'z') ch = getchar();
while (ch>='a'&&ch<='z') s[x]=s[x]*P+ch-'a'+1, ch=getchar();
} while(ch != '\r' && ch != '\n');
s[0] = x;
} //为什么改成 int 了? 因为长度只有5,把P设成26而不是常规字符串 Hash 能更快且不超 int,暂时达到了本题最优
这样会一开始先把原来没读完的换行符(Windows才可能没读完)筛掉,在洛谷或我们学校的评测机就都能过了。 数据范围
∣T∣ 表示的是 T 中单词的数量不是总长度,且题目数据范围有误,有 50006 的数据,数组开 5e4+10 就过了。