K-Dominant Character CodeForces

 

题目链接:https://vjudge.net/problem/CodeForces-888C

划一条线,使得不论怎么划线,都会出现一个特定的字符,那么这条线最短要多长。

用字符间隔考虑。

先判断哪些字符出现了,然后统计每个不同字符的出现次数,出现一次的和出现多次的分开判断。

出现一次的找到它的位置,取max(当前位置 - 字符串开始位置 + 1,字符串末位位置 - 当前位置 + 1)

然后遍历所有出现一次的字符,得出max的最小值,并记录,dis1

出现多次的找到相邻两个相同字符的间隔,取最大间隔的间隔k,再得出第一个出现的相同字符和开头的间隔+1,最后一个出现的相同字符和字符串末尾的间隔+1,和k比较取最大dis2

答案就是min(dis1,dis2)。


 

 1 #include <cstring>
 2 #include <iostream>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 
 7 #define inf (1LL << 30) 
 8 
 9 const int N = 100010;
10 char str[N];
11 int tmp[N];
12 int arr[N];
13 bool vis[30];
14 
15 int main(){
16 
17     ios::sync_with_stdio(false);
18     cin.tie(0);
19 
20     cin >> str;
21     int len = strlen(str) - 1;
22     
23     for(int i = 0; i <= len; i++){
24         arr[i] = str[i] - 'a' + 1;
25         vis[arr[i]] = true;  //哪些字符出现过
26     }
27     
28 
29     int dis1 = inf;
30     int dis2 = inf;
31     int l = 0;
32     for(int o = 0; o < 30; o++){ //'a'~'z'
33         if(!vis[o]) continue;
34 
35         l = 0;
36         for(int i = 0; i <= len; i++){
37             if(o == arr[i]) tmp[l++] = i;
38         }
39         --l;
40         //出现一次的
41         if(l == 0){
42             int v = 0;
43             v = max(v,max(tmp[l] - 0 + 1,len - tmp[0] + 1));
44             dis1 = min(dis1,v);
45         }
46         //出现多次的
47         else{
48             int v = 0;
49             for(int i = 1; i <= l; i++){
50                 v = max(v,tmp[i] - tmp[i - 1]);
51             }
52 
53 
54             v = max(v,tmp[0] - 0 + 1); //与字符串开头
55             v = max(v,len - tmp[l] + 1);//与字符串结尾
56 
57             dis2 = min(dis2,v);
58         }  
59     }
60 
61 
62     cout << min(dis1,dis2) << endl;
63 
64     getchar();getchar();
65 
66     return 0;
67 }

 

原文地址:https://www.cnblogs.com/SSummerZzz/p/11235003.html