week7_简单题_C_水题_hdu_5578+F_贪心_hdu_5583
Posted kid-yln
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了week7_简单题_C_水题_hdu_5578+F_贪心_hdu_5583相关的知识,希望对你有一定的参考价值。
C HDU_5578
求字符串中所有相同字母的最小距离H。
Input
实例个数T
然后T行字符串
字符串中仅含有小写字母。
1≤T≤50
1≤len≤1000(len为字符串长度)
Output
对于每个实例输出Case #t: H,表示第t个实例的答案是H。 如果没有相同的字母,H=-1。
Sample Input
2
ac
wxzayzxw
Sample Output
Case #1: -1
Case #2: 3
纯模拟_两层循环
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 char str[1009]; 8 int main() { 9 int t; 10 scanf("%d",&t); 11 int cnt=1; 12 while(t--) { 13 scanf("%s",str); 14 int len=strlen(str); 15 int ans=20000,flag=0; 16 for(int i=0; i<len; i++) { 17 for(int j=i+1; j<len; j++) { 18 if(str[j]==str[i]) { 19 ans=min(ans,j-i); 20 flag=1; 21 break; 22 } 23 } 24 } 25 if(!flag)ans=-1; 26 printf("Case #%d: %d ",cnt++,ans); 27 } 28 return 0; 29 }
另一种更快一点的_一层循环_利用数组存前导位置
1 #include<cstdio> 2 #include<cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 char s[1005]; 8 9 int x[100]; 10 int l; 11 int g=0; 12 int main() { 13 int T; 14 cin>>T; 15 int k=0; 16 while(T--) { 17 memset(x,-1,sizeof(x)); 18 memset(s,0,sizeof(s)); 19 l=10000; 20 //g=0; 21 scanf("%s",s); 22 int len=strlen(s); 23 for(int i=0; i<len; i++) { 24 int t=s[i]-‘a‘; 25 if(x[t]!=-1) { 26 int l1=i-x[t]; 27 l=min(l,l1); 28 } 29 x[t]=i; 30 } 31 if(l==10000)l=-1; 32 cout<<"Case #"<<++k<<": "<<l<<endl; 33 } 34 return 0; 35 }
F HDU_5583
现在有一个仅含0和1的字符串,规定字符串值的计算法方法是:
将字符串分成很多子串(连续),每个子串中不能同时含0和1。字符串的值为每个子串长度的平方和。例如00110 值为2*2+2*2+1*1=9。
这对你来说太简单了,你所要做的是更改字符串中的最多一个字符(可不改),当然了只能改为0或1,求出更改之后的字符串的最大值。
将字符串分成很多子串(连续),每个子串中不能同时含0和1。字符串的值为每个子串长度的平方和。例如00110 值为2*2+2*2+1*1=9。
这对你来说太简单了,你所要做的是更改字符串中的最多一个字符(可不改),当然了只能改为0或1,求出更改之后的字符串的最大值。
Input
实例个数T
然后T行字符串
1≤T≤50
1≤len≤100000 (len为字符串长度)
Output
对于每个实例输出
Case #t: ans,表示第t个实例的答案是ans。
Sample Input
2 00110 0010
Sample Output
Case #1: 13 Case #2: 16
纯模拟_TE了的答案_即使模拟也要注意最后一个长度记录下来
1 #include<cstdio> 2 #include<cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 char s[100005]; 8 9 int x[100]; 10 ll l; 11 int g=0; 12 int len; 13 ll f() { 14 15 char g=0; 16 ll lx=0; 17 ll lt=0; 18 for(int i=0; i<len; i++) { 19 if(g==s[i]) { 20 lx++; 21 } else { 22 lt+=lx*lx; 23 //cout<<g<<": "<<lx<<endl; 24 g=s[i]; 25 lx=1; 26 } 27 if(i==len-1) { 28 lt+=lx*lx; 29 //cout<<g<<": "<<lx<<endl; 30 } 31 } 32 return lt; 33 } 34 int main() { 35 int T; 36 cin>>T; 37 int k=0; 38 while(T--) { 39 memset(s,0,sizeof(s)); 40 //g=0; 41 scanf("%s",s); 42 len=strlen(s); 43 l=f(); 44 for(int i=0; i<len; i++) { 45 if(s[i]==‘1‘) { 46 s[i]=‘0‘; 47 ///cout<<f()<<endl; 48 l=max(l,f()); 49 s[i]=‘1‘; 50 } else { 51 s[i]=‘1‘; 52 //cout<<f()<<endl; 53 l=max(l,f()); 54 s[i]=‘0‘; 55 } 56 } 57 printf("Case #%d: %lld ",++k,l); 58 59 } 60 return 0; 61 }
改了一下, 贪心, 想要平方和最大, 已知, a^2+b^2<=(a+b)^2,显然不希望砍断长串,所以在各个串的边界改,
只能改一个, 那实际上就是求边界改的结果,每次改, 影响的是一对相邻串
如果模拟还是每次都要算一次(循环一次), 很有可能再TE, 那就转化成计算, 改边界,就是,某相邻串长度一个-1,一个+1,算此时新的结果,
和模拟一样也要注意最后一个记录下来
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 typedef long long ll; 6 using namespace std; 7 const int N=1e5+10; 8 ll dp[N]; 9 char str[N]; 10 int len; 11 int num; 12 ll sum; 13 ll ans; 14 void f() { 15 dp[1]=1; 16 for(int i=1; i<len; i++) { 17 if(str[i]==str[i-1]) { 18 dp[num]++; 19 } else { 20 sum+=dp[num]*dp[num]; 21 num++; 22 dp[num]++; 23 } 24 } 25 sum+=dp[num]*dp[num]; 26 if(num==1) { 27 ans=dp[1]*dp[1]; 28 } 29 } 30 int main() { 31 int t; 32 scanf("%d",&t); 33 int k=0; 34 while(t--) { 35 num=1; 36 ans=0; 37 sum=0; 38 scanf("%s",str); 39 len=strlen(str); 40 memset(dp,0,sizeof(dp)); 41 f(); 42 for(int i=2; i<=num; i++) { 43 if(dp[i]==1) { 44 ans=max(ans,sum+2*(dp[i-1]*dp[i+1]+dp[i-1]+dp[i+1])); 45 } else { 46 if(dp[i-1]>=dp[i]) { 47 ans=max(ans,sum+2*(dp[i-1]-dp[i]+1)); 48 } else ans=max(ans,sum+2*(dp[i]-dp[i-1]+1)); 49 } 50 } 51 cout<<"Case #"<<++k<<": "<<ans<<" "; 52 } 53 return 0; 54 }
以上是关于week7_简单题_C_水题_hdu_5578+F_贪心_hdu_5583的主要内容,如果未能解决你的问题,请参考以下文章