NOIP2011 统计单词数:
题目:
首先给出我一开始的代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,pos;
char s[20],t[1010000],ch;
int main(){
scanf("%s",s);
n=strlen(s);
getchar();
while(1){
scanf("%c",&ch);
if(ch=='\n') break;
t[m++]=ch;
}
for(int i=0;i<n;i++){
if(s[i]>='A' && s[i]<='Z')
s[i]=s[i]-'A'+'a';
}
for(int i=0;i<m;i++){
if(t[i]>='A' && t[i]<='Z')
t[i]=t[i]-'A'+'a';
}
pos=-1;
for(int i=0;i<m;i++){
if(i+n-1>=m) break;
bool match=true;
for(int j=0;j<n;j++){
if(t[i+j]!=s[j])
match=false;
break;
}
if(i!=0 && t[i-1] != ' ') match=false;
if(i+n<m && t[i+n] != ' ') match=false;
if(match){
++cnt;
if(pos==-1) pos=i;
}
}
if(cnt==0) printf("-1\n");
else printf("%d %d\n",cnt,pos);
return 0;
}
首先给出两个字符数组来存储单词和单词串,n,m分别代表了两个字符串的长度,读入之后再把他们化成小写,第一个细节在于用getchar吸收掉输入时的第一个空格,引入的pos代表了单词第一次出现的位置下标,cnt代表了单词一共出现了几次,通过暴力枚举,当大字符串的某一个和单词的首字母一致时开始判断是否完成匹配,并引入了bool变量作为依据看是否进行cnt的更新,思路还是很好想的,但是这样写的代码是会超时的,所以我想了一下之后,发现可以进行如下的优化:
#include<bits/stdc++.h>
using namespace std;
int main() {
char s[20], t[1010000];
int n, m;
scanf("%s", s);
n = strlen(s);
getchar();
m = fread(t, 1, sizeof(t), stdin);
for (int i = 0; i < n; i++) {
if (s[i] >= 'A' && s[i] <= 'Z')
s[i] = s[i] - 'A' + 'a';
}
for (int i = 0; i < m; i++) {
if (t[i] >= 'A' && t[i] <= 'Z')
t[i] = t[i] - 'A' + 'a';
}
int cnt = 0, pos = -1;
for (int i = 0; i < m - n + 1; i++) {
bool match = true;
for (int j = 0; j < n; j++) {
if (t[i + j] != s[j]) {
match = false;
break;
}
}
if (match && (i == 0 || t[i - 1] == ' ') && (i + n == m || t[i + n] == ' ')) {
++cnt;
if (pos == -1) pos = i;
}
}
if (cnt == 0) printf("-1\n");
else printf("%d %d\n", cnt, pos);
return 0;
}
思路其实也并未有多大的改变,改了几个小地方,减少了枚举次数同时用一个if判断出了cnt是否需要加1.