成都创新互联网站制作重庆分公司

一道简单题看y总C++代码风格优于我自己的地方

[[417678]]

题目

原题:AcWing 3805. 环形数组[1]

创新互联专注为客户提供全方位的互联网综合服务,包含不限于成都做网站、网站制作、房山网络推广、小程序开发、房山网络营销、房山企业策划、房山品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供房山建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com

给定一个长度为 的由小写字母构成的字符串 。

请你构造一个长度为 的由小写字母构成的字符串 。

要求,字符串 需满足:

  • 字符串 在字典序上大于字符串 。
  • 字符串 的字母集是字符串 的字母集的子集。一个字符串的字母集是指该字符串包含的所有不同字母的集合,例如 abadaba 的字母集为 。
  • 字符串 在字典序上尽可能小。

保证答案存在。

输入格式

第一行包含整数 ,表示共有 组测试数据。

每组数据第一行包含两个整数 和 。

第二行包含一个长度为 的字符串表示 。

输出格式

每组数据输出一行满足所有条件的字符串 。

数据范围

  • 前三个测试点满足 。
  • 所有测试点满足 ,。
  • 同一测试点内,所有 的和不超过 ,所有 的和不超过 。

输入样例:

 
 
 
  1. 4 
  2. 3 3 
  3. abc 
  4. 3 2 
  5. abc 
  6. 3 3 
  7. ayy 
  8. 2 3 
  9. ba 

输出样例:

 
 
 
  1. aca 
  2. ac 
  3. yaa 
  4. baa 

思路:分情况讨论

  • 当 k 大于 n 时,前 n 位不变,我们让 n 位开始填补出现过的最小字符就行
  • 当 k 小于等于 n 时,我们从原字符串 k - 1 位开始往前找,如果当前字符还有变小的可能,那么就让其变小,寻找停止,输出新字符串

代码

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4. using namespace std; 
  5.  
  6. int n, k; 
  7. bool used[26]; 
  8. string s, t; 
  9.  
  10. string tail() 
  11. { 
  12.     int i = 0; 
  13.     for (; i < 26; ++ i) 
  14.         if (used[i]) break; 
  15.     char a = 'a' + i; 
  16.     string res(k - n, a); 
  17.     return res; 
  18. } 
  19.  
  20. string get() 
  21. { 
  22.     char max_char; 
  23.     for (int i = 25; i >= 0; -- i) 
  24.     { 
  25.         if (used[i]) 
  26.         { 
  27.             max_char = 'a' + i; 
  28.             break; 
  29.         } 
  30.     } 
  31.     char min_char; 
  32.     for (int i = 0; i < 26; ++ i) 
  33.     { 
  34.         if (used[i]) 
  35.         { 
  36.             min_char = 'a' + i; 
  37.             break; 
  38.         } 
  39.     } 
  40.      
  41.     int i = k - 1; 
  42.     for (; i >= 0; -- i) 
  43.     { 
  44.         if (s[i] != max_char) break; 
  45.     } 
  46.      
  47.     string res1 = s.substr(0, i); 
  48.     string res2; 
  49.     for (int j = s[i] - 'a' + 1; j < 26; ++ j) 
  50.     { 
  51.         if (used[j]) 
  52.         { 
  53.             res2 = (char) 'a' + j; 
  54.             break; 
  55.         } 
  56.     } 
  57.     string res3(k - i - 1, min_char); 
  58.  
  59.     return res1 + res2 + res3; 
  60. } 
  61.  
  62. int main() 
  63. { 
  64.     int T; 
  65.     cin >> T; 
  66.     while (T --) 
  67.     { 
  68.         cin >> n >> k; 
  69.         cin >> s; 
  70.         memset(used, 0, sizeof used); 
  71.         for (int i = 0; i < s.size(); ++ i) used[s[i] - 'a'] = true; 
  72.         if (k > n) 
  73.         { 
  74.             t = s + tail(); 
  75.         } 
  76.         else 
  77.         { 
  78.             t = get(); 
  79.         } 
  80.         cout << t << endl; 
  81.     } 
  82. } 

可以看出我的代码思路很清晰,但是写得有一点冗余。

y 总代码

看看 y 总的代码。

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4.  
  5. using namespace std; 
  6.  
  7. const int N = 100010; 
  8.  
  9. int n, k; 
  10. char s1[N], s2[N]; 
  11. bool st[26]; 
  12.  
  13. char get_min() 
  14. { 
  15.     for (int i = 0; i < 26; i ++ ) 
  16.         if (st[i]) 
  17.             return i + 'a'; 
  18.     return -1; 
  19. } 
  20.  
  21. char get_next(int t) 
  22. { 
  23.     for (int i = t + 1; i < 26; i ++ ) 
  24.         if (st[i]) 
  25.             return i + 'a'; 
  26.     return -1; 
  27. } 
  28.  
  29. int main() 
  30. { 
  31.     int T; 
  32.     scanf("%d", &T); 
  33.     while (T -- ) 
  34.     { 
  35.         scanf("%d%d", &n, &k); 
  36.         scanf("%s", s1); 
  37.         memset(st, 0, sizeof st); 
  38.         for (int i = 0; i < n; i ++ ) st[s1[i] - 'a'] = true; 
  39.         if (k > n) 
  40.         { 
  41.             printf("%s", s1); 
  42.             char c = get_min(); 
  43.             for (int i = n; i < k; i ++ ) printf("%c", c); 
  44.             puts(""); 
  45.         } 
  46.         else 
  47.         { 
  48.             s2[k] = 0; 
  49.             for (int i = k - 1; i >= 0; i -- ) 
  50.             { 
  51.                 char c = get_next(s1[i] - 'a'); 
  52.                 if (c != -1) 
  53.                 { 
  54.                     s2[i] = c; 
  55.                     for (int j = 0; j < i; j ++ ) s2[j] = s1[j]; 
  56.                     break; 
  57.                 } 
  58.                 s2[i] = get_min(); 
  59.             } 
  60.             puts(s2); 
  61.         } 
  62.     } 
  63.  
  64.     return 0; 
  65. } 
  66.  
  67. // 作者:yxc 
  68. // 链接:https://www.acwing.com/activity/content/code/content/1634481/ 
  69. // 来源:AcWing 
  70. // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

很简洁。

经验:

  • char s[]; puts(s); 中, puts 遇到 \0 注意是 char s[k] = 0 而不是 char s[k] = '0' 字符串停止输出。

参考资料

[1]AcWing 3805. 环形数组:

https://www.acwing.com/activity/content/problem/content/5457/

 


分享标题:一道简单题看y总C++代码风格优于我自己的地方
网站路径:http://cxhlcq.com/article/codphso.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部