标签:des style blog http color io os ar java
11754936 | 2014-09-29 10:08:45 | Accepted | 5056 | 31MS | 392K | 1257 B | G++ | czy |
好简单的思路,怎么就没想到呢。。。。。
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 250 Accepted Submission(s): 98
官方题解:
1003 Boring count
枚举字符串下标i,每次计算以i为结尾的符合条件的最长串。那么以i为结尾的符合条件子串个数就是最长串的长度。求和即可。
计算以i为结尾的符合条件的最长串两种方法:
1.维护一个起点下标startPos,初始为1。如果当前为i,那么cnt[str[i]]++,如果大于k的话,就while( str[startPos] != str[i+1] ) cnt[str[startPos]]--, startPos++; 每次都保证 startPos~i区间每个字母个数都不超过k个。ans += ( i-startPos+1 )。 时间复杂度O(n)
2.预处理出所有字母的前缀和。然后通过二分找出以i为结尾的符合条件的最长串的左边界。时间复杂度O(nlogn),写的不够好的可能超时。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<map> 9 #include<string> 10 11 #define N 100005 12 #define M 15 13 #define mod 10000007 14 //#define p 10000007 15 #define mod2 100000000 16 #define ll long long 17 #define LL long long 18 #define maxi(a,b) (a)>(b)? (a) : (b) 19 #define mini(a,b) (a)<(b)? (a) : (b) 20 21 using namespace std; 22 23 int T; 24 int n; 25 ll l; 26 char s[N]; 27 ll ans; 28 ll vis[30]; 29 ll k; 30 ll te; 31 32 void ini() 33 { 34 ans=0; 35 scanf("%s",s); 36 scanf("%I64d",&k); 37 l=strlen(s); 38 memset(vis,0,sizeof(vis)); 39 } 40 41 42 void solve() 43 { 44 ll i; 45 ll pre; 46 pre=0; 47 for(i=0;i<l;i++){ 48 vis[ s[i]-‘a‘ ]++; 49 while(vis[ s[i]-‘a‘ ]>k){ 50 vis[ s[pre]-‘a‘ ]--; 51 pre++; 52 } 53 ans+=i-pre+1; 54 } 55 } 56 57 void out() 58 { 59 printf("%I64d\n",ans); 60 } 61 62 int main() 63 { 64 //freopen("data.in","r",stdin); 65 //freopen("data.out","w",stdout); 66 scanf("%d",&T); 67 // for(int ccnt=1;ccnt<=T;ccnt++) 68 while(T--) 69 // while(scanf("%d",&n)!=EOF) 70 { 71 // if(n==0 && m==0) break; 72 //printf("Case %d: ",ccnt); 73 ini(); 74 solve(); 75 out(); 76 } 77 78 return 0; 79 }
标签:des style blog http color io os ar java
原文地址:http://www.cnblogs.com/njczy2010/p/3999620.html