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 }
View Code

 

另一种更快一点的_一层循环_利用数组存前导位置

技术图片
 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 }
View Code

 

 

F    HDU_5583

现在有一个仅含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 }
View Code

改了一下,  贪心, 想要平方和最大, 已知, 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 }
View Code

 

 

 

 

 

以上是关于week7_简单题_C_水题_hdu_5578+F_贪心_hdu_5583的主要内容,如果未能解决你的问题,请参考以下文章

涨姿势题2_水题_两种解法

$HDU 2020$ 多校第一场

HDU_2191_多重背包

hdu_1012(水题。。。不能再水)

HDU1009_FatMouse&#39; Trade贪心水题

python学习笔记_week7