题目描述
给定一个由英文字母组成的字符串,求出一个子串,满足如下要求:该子串所包含的元音字母(a,e,i,o,u)的个数不大于辅音字母的个数的两倍。
你的任务是找到最长的满足要求的子串,输出其长度,并且输出最长的满足条件的子串的个数(区分2个子串是否不同的因素是起始位置和长度)。
输入
输入包括多组数据,每组数据包括一行,每行有一个由英文字母组成的字符串(长度<=200000)。
输出
每组数据输出一行,每行包括2个整数a和b,其中a代表最长子串的长度,b代表最长子串的个数,若不存在这样的子串,则输出“No solution”(不含引号)。
样例输入
abo oeis
样例输出
3 1 3 1
这个题又把我害了,原来gets()来读WA两次,不知道为什么,后来改成scanf,AC了
一开始我二分长度,后来想想不对,改为枚举长度,从最长的开始枚举,一旦可以就返回,这样竟然0msAC
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; const int maxn=200000+10; int get(char c) { if (c=='A' || c=='a' || c=='E' || c=='e' || c=='I' || c=='i' || c=='O' || c=='o' || c=='U' || c=='u') return 1; else return 0; } char str[maxn]; int a[maxn],L; bool if_find(int Len) { int st=0,ed=Len,n,m; while(ed<=L) { n=a[ed]-a[st]; m=Len-n; if (n<=2*m) return true; ed++; st++; } return false; } int find() { for (int i=L;i>=0;i--) if (if_find(i)) return i; } int get_num(int Len) { int st=0,ed=Len,n,m,ans=0; while(ed<=L) { n=a[ed]-a[st]; m=Len-n; if (n<=2*m) ans++; ed++; st++; } return ans; } int main() { while(scanf("%s",str)!=EOF) { L=strlen(str); a[0]=0; for (int i=0;i<L;i++) a[i+1]=a[i]+get(str[i]); int ans=find(); if (ans==0) { printf("No solution "); continue; } printf("%d",ans); ans=get_num(ans); printf(" %d ",ans); } return 0; }
作者 chensunrise