A Count Task HDU 6480
http://acm.hdu.edu.cn/showproblem.php?pid=6480
https://vjudge.net/contest/342215#problem/G
解题思路:
其实我就是想水个糖,keke
对于这道题,我想到的有两种写法。一种是用数列求和公式,另一种就是用动态规划了。(都是比赛后才会的orz)
对于第一种的写法,我们可以数相同的字母的个数,我习惯这样数。
int i; for(i=0;str[i]!='\0';i++) { if(i==0) ch=str[i]; else if(str[i]==ch){ ans++; } ......
当遇到与ch不相同的字符时,就更新并计算sum的值。
完整代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<math.h> 5 #include<limits.h> 6 7 #define N 100010 8 9 typedef long long int ll; 10 11 int main() 12 { 13 int t; 14 char ch; 15 char str[N]; 16 scanf("%d",&t); 17 getchar(); 18 while(t--) 19 { 20 ll sum=0; 21 ll ans=1; 22 gets(str); 23 int i; 24 for(i=0;str[i]!='\0';i++) 25 { 26 if(i==0) ch=str[i]; 27 else if(str[i]==ch){ 28 ans++; 29 } 30 else{ 31 sum+=(1+ans)*ans/2; //计算前面相同的字母的个数 32 ans=1; //更新计数器 33 ch=str[i]; //更新当前字符 34 } 35 } 36 sum+=(1+ans)*ans/2; //防止未统计上最后的连续字符 37 printf("%lld\n",sum); 38 } 39 return 0; 40 }
第二种解法:
简单说一下思路,因为求的是子字符串的总长度,因此就想到可不可以建立一个数组dp来记录到i处的子串的长度,然后把所有dp数组里面的数加起来。
因此得到了如下代码:
1 #include <math.h> 2 #include <stdio.h> 3 #include <ctype.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #define N 100010 8 9 typedef long long int ll; 10 11 int main() 12 { 13 int t; 14 scanf("%d", &t); 15 getchar(); 16 while(t--){ //t个测试实例 17 char s[N]; 18 int dp[N]={0}; //记录子段的长度 19 int i, len; 20 ll sum=0; 21 scanf("%s", s); 22 len=strlen(s); 23 for(i=0; i<len; i++){ 24 if(i==0) dp[i]=1; //为第一个字符时,长度为1 25 else{ 26 dp[i]=1; //先给dp[i]一个长度为1的初始值 27 if(s[i]==s[i-1]) //当当前字符与前一个字符相同时(即连续) 28 dp[i]+=dp[i-1]; //更新到i的子串的长度 29 } 30 sum+=dp[i]; //求总和 31 } 32 printf("%I64d\n", sum); 33 } 34 return 0; 35 }