百度之星2018资格赛1002题解

Posted syx-799

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了百度之星2018资格赛1002题解相关的知识,希望对你有一定的参考价值。

作为退役的老人家来光顾光顾百度之星。

据说资格赛水过一道题就行。。。就写那个签到题吧。orz

题目糊上,,,

度度熊的字符串课堂开始了!要以像度度熊一样的天才为目标,努力奋斗哦!

为了检验你是否具备不听课的资质,度度熊准备了一个只包含大写英文字母的字符串 A[1,n]=a1a2?anA[1,n]=a?1??a?2???a?n??,接下来他会向你提出 qq 个问题 (l,r)(l,r),你需要回答字符串 A[l,r]=alal+1?arA[l,r]=a?l??a?l+1???a?r?? 内有多少个非空子串是 A[l,r]A[l,r] 的所有非空子串中字典序最小的。这里的非空子串是字符串中由至少一个位置连续的字符组成的子序列,两个子串是不同的当且仅当这两个子串内容不完全相同或者出现在不同的位置。

记 ∣S∣S∣ 为字符串 SS 的长度,对于两个字符串 SS 和 TT ,定义 SS 的字典序比 TT 小,当且仅当存在非负整数 k(≤min(∣S∣,∣T∣))k(min(S,T)) 使得 SS 的前 kk 个字符与 TT 的前 kk 个字符对应相同,并且要么满足 ∣S∣=kS=k 且 ∣T∣>kT>k,要么满足 k<min(∣S∣,∣T∣)k<min(S,T) 且 SS 的第 k+1k+1 个字符比 TT 的第 k+1k+1 个字符小。例如 "AA" 的字典序比 "AAA" 小,"AB" 的字典序比 "BA" 小。

一开始看这个题,MD这么复杂,一看就是dalao出的题。

抓住关键词,字典序最小,首先考虑字符串长度最小,emmmm,当然是一个字母长度最小。

所以这个题就变成了,在一段字符区间中统计最小的那个字母出现了几次。

emmmmm,能把这么水的一个题说的这么高大上,我也是给出题人跪了。。。orz

用个前缀和思想。统计一下到当前位置每个字母出现几次,数组下标1~26表示A~Z出现的次数。

查询的时候从1到26循环若a[r]-a[l-1]不为零,就是他了,输出,跳出循环(这样字典序最小,因为相当于从A向Z找)。

说了这么多我相信都是废话,诸位大佬肯定能A掉这个题。emmmmmm

上代码。(丑得一逼)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <vector>
 5 #include <queue>
 6 #include <deque>
 7 #include <stack>
 8 #include <string>
 9 #include <cstdlib>
10 #include <cstring>
11 #define LL long long
12 using namespace std;
13 void read(int &x){
14     char ch;x = 0;ch = getchar();
15     while(ch < 0 || ch > 9) ch = getchar();
16     while(ch >= 0 && ch <= 9){
17         x = x*10+ch-0;
18         ch = getchar();
19     }
20 }
21 struct H {
22     int qq[26];
23 }cc[100000+5];
24 int T = 0,n,q,l,r,minn,num,cntt;
25 int cnt[Z+5];
26 char ch[100000+5];
27 int main(){
28     read(T);
29     while(T--){
30         printf("Case #");++cntt;
31         printf("%d:
",cntt);
32         read(n);read(q);
33         for(int i = 1;i <= n;i++)
34             scanf("%c",&ch[i]);
35         for(int i = 1;i <= n;i++){
36             cc[i] = cc[i-1];
37             cc[i].qq[ch[i]-A]++;
38         }
39         for(int i = 1;i <= q;i++){
40             read(l);read(r);
41             if(l == r){
42                 printf("1
");
43                 continue;
44             }
45             else {
46                 for(int j = 0;j < 26;j++){
47                     if(cc[r].qq[j]-cc[l-1].qq[j]!=0){
48                         printf("%d
",cc[r].qq[j]-cc[l-1].qq[j]);
49                         break;
50                     }
51                 }
52             }
53         }
54     }
55     return 0;
56 }

 

以上是关于百度之星2018资格赛1002题解的主要内容,如果未能解决你的问题,请参考以下文章

2018百度之星资格赛1002 子串查询

2018"百度之星"程序设计大赛 - 资格赛 - 题集

2014百度之星资格赛题解

2018百度之星资格赛T2 子串查询

2014年百度之星程序设计大赛 - 资格赛 1002 Disk Schedule(双调欧几里得旅行商问题)

2017 百度之星 资格赛 题解