zoukankan      html  css  js  c++  java
  • 9-10月刷题Keep On

    看到日期有点慌啊……趁着这几天准备笔试,抓住9月的尾巴补一篇随笔

    9.28

    【字符串】Sherlock - HackerRank

    Manacher算法(“马拉车”算法)

    尴尬……上面这道题好像不能直接用马拉车算法,我至今也没弄出来

    10.2

    【字典/哈希】Frequency Queries - HackerRank

      可能太久没做题了,逻辑半天都捋不清楚!此题的关键是维护两个Map,这样可以有两个键名供查找。易错点是注意增删操作影响的元素频数,且需要判断Map中没有该元素的两种情况(根本没有对应的键,或键名对应的值为0)

    参考代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 string ltrim(const string &);
      4 string rtrim(const string &);
      5 vector<string> split(const string &);
      6 
      7 // Complete the freqQuery function below.
      8 vector<int> freqQuery(vector<vector<int>> queries) {
      9     unordered_map<int, int> UMp1;//事后发现此题的时间效率与是否是哈希的map好像没关系,只要是字典O(1)查找就行
     10     unordered_map<int, int> UMp2;
     11     vector<int> ans;
     12     int len = queries.size();
     13     for(int i = 0; i < len; i++){
     14         int op = queries[i][0], ob = queries[i][1];
     15         if(op == 1){
     16             if(UMp1.find(ob) != UMp1.end() && UMp1[ob] != 0){
     17                 UMp1[ob] ++;
     18                 if(UMp2.find(UMp1[ob]) != UMp2.end() && UMp2[UMp1[ob]] != 0){
     19                     UMp2[ UMp1[ob] ] ++;
     20                 }
     21                 else UMp2[ UMp1[ob] ] = 1;
     22                 UMp2[ UMp1[ob]-1 ] --;
     23             }
     24             else{
     25                 UMp1[ob] = 1;
     26                 if(UMp2.find(1) != UMp2.end()  && UMp2[1] != 0){
     27                     UMp2[1] ++;
     28                 }
     29                 else UMp2[1] = 1;
     30             }
     31         }
     32         else if(op == 2){
     33             if(UMp1.find(ob) != UMp1.end() && UMp1[ob] != 0){
     34                 UMp1[ob] --;
     35                 if(UMp2.find(UMp1[ob]) != UMp2.end() && UMp2[UMp1[ob]] != 0) UMp2[ UMp1[ob] ] ++;
     36                 else{
     37                     UMp2[ UMp1[ob] ] = 1;
     38                 }
     39                 if(UMp2[UMp1[ob]+1] > 0) UMp2[ UMp1[ob]+1 ] --;
     40             }           
     41         }
     42         else if(op == 3){
     43             if(UMp2.find(ob) == UMp2.end() || UMp2[ob] == 0) ans.push_back(0);
     44             else ans.push_back(1);
     45         }
     46     }
     47     return ans;
     48 }
     49 
     50 int main()
     51 {
     52     ofstream fout(getenv("OUTPUT_PATH"));
     53 
     54     string q_temp;
     55     getline(cin, q_temp);
     56 
     57     int q = stoi(ltrim(rtrim(q_temp)));
     58 
     59     vector<vector<int>> queries(q);
     60 
     61     for (int i = 0; i < q; i++) {
     62         queries[i].resize(2);
     63 
     64         string queries_row_temp_temp;
     65         getline(cin, queries_row_temp_temp);
     66 
     67         vector<string> queries_row_temp = split(rtrim(queries_row_temp_temp));
     68 
     69         for (int j = 0; j < 2; j++) {
     70             int queries_row_item = stoi(queries_row_temp[j]);
     71 
     72             queries[i][j] = queries_row_item;
     73         }
     74     }
     75 
     76     vector<int> ans = freqQuery(queries);
     77 
     78     for (int i = 0; i < ans.size(); i++) {
     79         fout << ans[i];
     80 
     81         if (i != ans.size() - 1) {
     82             fout << "
    ";
     83         }
     84     }
     85 
     86     fout << "
    ";
     87 
     88     fout.close();
     89 
     90     return 0;
     91 }
     92 
     93 string ltrim(const string &str) {
     94     string s(str);
     95 
     96     s.erase(
     97         s.begin(),
     98         find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)))
     99     );
    100 
    101     return s;
    102 }
    103 
    104 string rtrim(const string &str) {
    105     string s(str);
    106 
    107     s.erase(
    108         find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(),
    109         s.end()
    110     );
    111 
    112     return s;
    113 }
    114 
    115 vector<string> split(const string &str) {
    116     vector<string> tokens;
    117 
    118     string::size_type start = 0;
    119     string::size_type end = 0;
    120 
    121     while ((end = str.find(" ", start)) != string::npos) {
    122         tokens.push_back(str.substr(start, end - start));
    123 
    124         start = end + 1;
    125     }
    126 
    127     tokens.push_back(str.substr(start));
    128 
    129     return tokens;
    130 }
    View Code

     10.3

    【排序】Fraudulent Activity Notifications - HackerRank

      通过此题首次接触到了基数排序计数排序!(暂时没空自己总结了,贴两篇博文链接好了。)这题还是有点东西滴~

      另外,桶排序是计数排序的优化版本,记得补上。

    参考代码:

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 vector<string> split_string(string);
      6 
      7 // Complete the activityNotifications function below.
      8 int activityNotifications(vector<int> expenditure, int d) {
      9     int n = expenditure.size(), cnt = 0, Max = -1, Min = 300;
     10     for(int i = 0; i < n; ++i){
     11         Max = max(Max, expenditure[i]);
     12         Min = min(Min, expenditure[i]);
     13     }
     14     vector<int> votes(Max - Min + 1);//从最小到最大数,以最小数为基准。此题的范围是0-200,故桶排序很高效
     15     if(d%2 == 1){
     16         for(int i = 0; i < d; ++i){
     17             votes[expenditure[i] - Min] ++;
     18         }
     19         for(int i = d; i < n; ++i){
     20             int k = d/2+1, j = -1;//计算中位数的区间长度d为奇数时,就遍历到前d/2+1个数
     21             while(k > 0){
     22                 j ++;
     23                 k -= votes[j];
     24             }
     25             if(expenditure[i] >= 2 * (j+Min)) cnt ++;//后面不要忘了每次计算引用下标都要调整一个最小数
     26             votes[ expenditure[i - d] - Min] --;
     27             votes[ expenditure[i] - Min] ++;
     28         }
     29     }
     30     else{
     31         for(int i = 0; i < d; ++i){
     32             votes[expenditure[i] - Min] ++;
     33         }
     34         for(int i = d; i < n; ++i){
     35             int k = d/2, j = -1, tmp = 0;//对于d是偶数的情况,分两次取两个k,用tmp记录和的值
     36             while(k > 0){
     37                 j ++;
     38                 k -= votes[j];
     39             }
     40             tmp += j + Min;
     41             if(k<0) tmp *= 2;//如果这两个中间数相同,则k一定会减为负数
     42             else{
     43                 k = 1; //如果不同,k再向后取一个
     44                 while(k > 0){
     45                     j ++;
     46                     k -= votes[j];
     47                 }
     48                 tmp += j + Min;
     49             }
     50             if(expenditure[i] >= tmp) cnt ++;
     51             votes[ expenditure[i - d] - Min] --;
     52             votes[ expenditure[i] - Min] ++;
     53         }
     54     }
     55     return cnt;
     56 }
     57 
     58 int main()
     59 {
     60     ofstream fout(getenv("OUTPUT_PATH"));
     61 
     62     string nd_temp;
     63     getline(cin, nd_temp);
     64 
     65     vector<string> nd = split_string(nd_temp);
     66 
     67     int n = stoi(nd[0]);
     68 
     69     int d = stoi(nd[1]);
     70 
     71     string expenditure_temp_temp;
     72     getline(cin, expenditure_temp_temp);
     73 
     74     vector<string> expenditure_temp = split_string(expenditure_temp_temp);
     75 
     76     vector<int> expenditure(n);
     77 
     78     for (int i = 0; i < n; i++) {
     79         int expenditure_item = stoi(expenditure_temp[i]);
     80 
     81         expenditure[i] = expenditure_item;
     82     }
     83 
     84     int result = activityNotifications(expenditure, d);
     85 
     86     fout << result << "
    ";
     87 
     88     fout.close();
     89 
     90     return 0;
     91 }
     92 
     93 vector<string> split_string(string input_string) {
     94     string::iterator new_end = unique(input_string.begin(), input_string.end(), [] (const char &x, const char &y) {
     95         return x == y and x == ' ';
     96     });
     97 
     98     input_string.erase(new_end, input_string.end());
     99 
    100     while (input_string[input_string.length() - 1] == ' ') {
    101         input_string.pop_back();
    102     }
    103 
    104     vector<string> splits;
    105     char delimiter = ' ';
    106 
    107     size_t i = 0;
    108     size_t pos = input_string.find(delimiter);
    109 
    110     while (pos != string::npos) {
    111         splits.push_back(input_string.substr(i, pos - i));
    112 
    113         i = pos + 1;
    114         pos = input_string.find(delimiter, i);
    115     }
    116 
    117     splits.push_back(input_string.substr(i, min(pos, input_string.length()) - i + 1));
    118 
    119     return splits;
    120 }
    View Code

     【字符串】Sherlock And Valid String - HackerRank

      这题也好细节啊……天。

    参考代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 // Complete the isValid function below.
     6 string isValid(string s) {
     7     int n = s.size();
     8     int type[26];
     9     memset(type, 0 ,sizeof(type));
    10     for(int i = 0; i < n; ++i){
    11         type[s[i]-'a'] ++;
    12     }
    13     int k1 = 0, k2 = 0, n1 = 0, n2 = 0;
    14     for(int i = 0; i < 26; ++i){
    15         if(n1 > 1 && n2 > 1) return "NO";//出现两种占主重复次数
    16         if(n1 == 1 && n2 > 1 && k1 != k2+1 && k1 != 1) return "NO";//出现两种无法调和的重复次数(无法通过-1合并为同一次数或降低字母多样性)
    17         if(n2 == 1 && n1 > 1 && k2 != k1+1 && k2 != 1)return "NO";
    18         if(type[i] > 0){//type[i]是字母('a'+i)的出现次数
    19             if(type[i] == k1) n1++;
    20             else if(type[i] == k2) n2++;
    21             else if(k1 == 0){
    22                 k1 = type[i];
    23                 n1 = 1;
    24             }
    25             else if(k2 == 0){
    26                 k2 = type[i];
    27                 n2 = 1;
    28             }
    29             else return "NO";//出现三种重复次数
    30         }
    31     }
    32     return "YES";
    33 }
    34 
    35 int main()
    36 {
    37     ofstream fout(getenv("OUTPUT_PATH"));
    38 
    39     string s;
    40     getline(cin, s);
    41 
    42     string result = isValid(s);
    43 
    44     fout << result << "
    ";
    45 
    46     fout.close();
    47 
    48     return 0;
    49 }
    View Code

     10.4

    【字符串】Special String Again - HackerRank

      O(1)复杂度的解法↓ [呲牙][呲牙]

    参考代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 // Complete the substrCount function below.
     4 long substrCount(int n, string s) {
     5     long cnt = 0;
     6     //Save trailing numbers
     7     vector<int> trail(n);
     8     char pre = s[0];
     9     trail[0] = 1;
    10     for(int i = 1; i <n; ++i){
    11         if(s[i] == pre){
    12             trail[i] = trail[i - 1] + 1;
    13         }
    14         else{
    15             pre = s[i];
    16             trail[i] = 1;
    17         }
    18     }
    19     //Save trailing numbers of the reverse order
    20     vector<int> rev_trail(n);
    21     char rev_pre = s[n-1];
    22     rev_trail[n-1] = 1;
    23     for(int i = n-2; i >= 0; --i){
    24         if(s[i] == rev_pre){
    25             rev_trail[i] = rev_trail[i + 1] + 1;
    26         }
    27         else{
    28             rev_pre = s[i];
    29             rev_trail[i] = 1;
    30         }
    31     }
    32     //Calculate pattern 1
    33     for(int i = 0; i < n; ++i){
    34         if(i + 1 < n && trail[i] < trail[i+1]) continue;
    35         cnt += trail[i] * (trail[i] + 1) / 2;
    36     }
    37     //Calculate pattern 2
    38     for(int i = 1; i < n - 1; ++i){
    39         if(s[i-1] == s[i+1] && trail[i] == 1){
    40             int l1 = trail[i-1], l2 = rev_trail[i+1];
    41             cnt += min(l1, l2);
    42         }
    43     }
    44     return cnt;
    45 }
    46 
    47 int main()
    48 {
    49     ofstream fout(getenv("OUTPUT_PATH"));
    50 
    51     int n;
    52     cin >> n;
    53     cin.ignore(numeric_limits<streamsize>::max(), '
    ');
    54 
    55     string s;
    56     getline(cin, s);
    57 
    58     long result = substrCount(n, s);
    59 
    60     fout << result << "
    ";
    61 
    62     fout.close();
    63 
    64     return 0;
    65 }
    View Code
    用代码改变世界!就是这样,喵!
  • 相关阅读:
    PAT Basic 1077 互评成绩计算 (20 分)
    PAT Basic 1055 集体照 (25 分)
    PAT Basic 1059 C语言竞赛 (20 分)
    PAT Basic 1072 开学寄语 (20 分)
    PAT Basic 1049 数列的片段和 (20 分)
    蓝桥杯BASIC-13 数列排序
    蓝桥杯入门——3.序列求和
    蓝桥杯入门——2.圆的面积
    蓝桥杯入门——1.Fibonacci数列
    树的总结(遍历,BST,AVL原型,堆,练习题)
  • 原文地址:https://www.cnblogs.com/Song-Meow/p/13744173.html
Copyright © 2011-2022 走看看