• Google Code Jam 2019 Round 1A 题解


    A. Alien Rhyme

    题意:

    思路:将字符反向插入一颗Trie,然后自下而上的贪心即可,即先选后缀长的,再选后缀短的。

    实现:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <iomanip>
      5 
      6 #include <vector>
      7 #include <cstring>
      8 #include <string>
      9 #include <queue>
     10 #include <deque>
     11 #include <stack>
     12 #include <map>
     13 #include <set>
     14 
     15 #include <utility>
     16 #include <list>
     17 
     18 #include <cmath>
     19 #include <algorithm>
     20 #include <cassert>
     21 #include <bitset>
     22 #include <complex>
     23 #include <climits>
     24 #include <functional>
     25 #include <unordered_set>
     26 #include <unordered_map>
     27 using namespace std;
     28 
     29 typedef long long ll;
     30 typedef pair<int, int> ii;
     31 typedef pair<ll, ll> l4;
     32 typedef pair<double, double> dd;
     33 #define mp make_pair
     34 #define pb push_back
     35 
     36 #define debug(x) cerr << #x << " = " << x << " "
     37 const int maxlen = 50+1;
     38 const int N = 1000+1;
     39 const int maxn = N * maxlen;
     40 const int A = 26;
     41 int g[maxn][A], cnt[maxn], tot;
     42 inline int newnode()
     43 {
     44     memset(g[tot], 0, sizeof(g[tot]));
     45     cnt[tot] = 0;
     46     return tot++;
     47 }
     48 void init()
     49 {
     50     tot = 0;
     51     newnode();
     52 }
     53 char s[maxlen];
     54 void insert()
     55 {
     56     int len = strlen(s);
     57     int cur = 0;
     58     for (int i = len-1; i >= 0; --i)
     59     {
     60         int c = s[i] - 'A';
     61         if (g[cur][c] == 0) g[cur][c] = newnode();
     62         cur = g[cur][c];
     63         ++cnt[cur];
     64     }
     65 }
     66 int solve(int cur)
     67 {
     68     if (cnt[cur] == 1) return 0;
     69     int ret = 0;
     70     for (int c = 0; c < A; ++c)
     71         if (g[cur][c])
     72         {
     73             //cerr << "from " << cur << " via " << char('A'+c) << " to " << g[cur][c] << endl;
     74             ret += solve(g[cur][c]);
     75         }
     76     int tmp = cnt[cur] - ret;
     77     if (tmp >= 2) ret += 2;
     78     return ret;
     79 }
     80 int main()
     81 {
     82 //    ios::sync_with_stdio(false);
     83 //    cin.tie(0);
     84 //    int T; cin >> T;
     85     int T; scanf("%d", &T);
     86     for (int kase = 1; kase <= T; ++kase)
     87     {
     88         int n; scanf("%d", &n);
     89         init();
     90         for (int i = 0; i < n; ++i)
     91         {
     92             scanf("%s", s);
     93             insert();
     94         }
     95         printf("Case #%d: %d
    ", kase, solve(0));
     96     }
     97 }
     98 /*
     99  1
    100  10 5 5
    101  101010101000010100101
    102  0 2 4 6 8 13 15  18 20
    103  */
    View Code

    B. Golf Gophers

    题意:

    思路:设所求的人数为TARGET。我们可以把18个计数器弱化为1个计数器,具体就是每个计数器的阈值Bi都设为同一个,计作MOD,这样我们每次询问之后,所有计数器被拨动之后值的和就等于 TARGET%MOD。这个看起来是不是很像中国剩余定理?发现小于18的质数刚好7个{2,3,5,7,11,13,17},而且每个质数的最高幂{16,9,5,7,11,13,17}的乘积大于1e6(TARGET的最大可能值),所以就迎刃而解了

    实现:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <iomanip>
      5 
      6 #include <vector>
      7 #include <cstring>
      8 #include <string>
      9 #include <queue>
     10 #include <deque>
     11 #include <stack>
     12 #include <map>
     13 #include <set>
     14 
     15 #include <utility>
     16 #include <list>
     17 
     18 #include <cmath>
     19 #include <algorithm>
     20 #include <cassert>
     21 #include <bitset>
     22 #include <complex>
     23 #include <climits>
     24 #include <functional>
     25 #include <unordered_set>
     26 #include <unordered_map>
     27 using namespace std;
     28 
     29 typedef long long ll;
     30 typedef pair<int, int> ii;
     31 typedef pair<ll, ll> l4;
     32 typedef pair<double, double> dd;
     33 #define mp make_pair
     34 #define pb push_back
     35 
     36 #define debug(x) cerr << #x << " = " << x << " "
     37 
     38 
     39 int T, N, M;
     40 vector<int> query(int mycnt, int myvalue, int judgecnt)
     41 {
     42     for (int i = 0; i < mycnt; ++i)
     43         printf("%d%c", myvalue, " 
    "[i+1==mycnt]);
     44     fflush(stdout);
     45     vector<int> ret(judgecnt, 0);
     46     for (auto & e : ret)
     47         scanf("%d", &e);
     48     return ret;
     49 }
     50 vector<int> factor = {16, 9, 5, 7, 11, 13, 17};
     51 vector<int> inv;
     52 int all;
     53 ll power(ll base, ll p, ll mod)
     54 {
     55     ll ret = 1 % mod;
     56     while (p)
     57     {
     58         if (p&1) ret = ret * base % mod;
     59         base = base * base % mod;
     60         p >>= 1;
     61     }
     62     return ret;
     63 }
     64 ll inverse(ll base, ll mod)
     65 {
     66     return power(base, mod-2, mod);
     67 }
     68 void preprocess()
     69 {
     70     all = 1;
     71     for (auto e : factor) all *= e;
     72     for (auto e : factor)
     73     {
     74         int y = all/e;
     75         ll _inv = -1;
     76         for (int i = 1; i < e; ++i)
     77             if (1ll * i * y % e == 1)
     78             {
     79                 _inv = i;
     80                 break;
     81             }
     82         assert(_inv != -1);
     83         inv.pb(y * _inv);
     84     }
     85 }
     86 const int MILL = 18;
     87 int process(int factor)
     88 {
     89     auto response = query(MILL, factor, MILL);
     90     int ret = 0;
     91     for (auto e : response) (ret += e) %= factor;
     92     return factor;
     93 }
     94 
     95 void solve()
     96 {
     97     ll ret = 0;
     98     for (int i = 0; i < factor.size(); ++i)
     99     {
    100         (ret += 1ll * process(factor[i]) * inv[i] % all) %= all;
    101     }
    102     auto tmp = query(1, ret, 1);
    103     assert(tmp.size() == 1 && tmp.front() == 1);
    104 }
    105 int main()
    106 {
    107     preprocess();
    108     scanf("%d %d %d", &T, &N, &M);
    109     for (int kase = 1; kase <= T; ++kase)
    110         solve();
    111 }
    View Code

    C. Pylons

    题意:

    思路:比较明显的是在r或c比较大的时候,可以利用样例里的思路拓展一下(也许需要tweak一下奇偶性的问题)。r和c都比较小的时候可以利用和traveling salesman problem类似的方式打表(也可以暴搜)。应该是有比较规律性的解法,这里没有细想。

    实现:写的太丑了就不贴了,而且我大约写了另外两个文件来生成数据/测试/打表。

  • 相关阅读:
    关于产品那些事
    关于“编程的本质”的探讨
    分享一款在线贝塞尔曲线调试器
    HTML、CSS、JS对unicode字符的不同处理
    HTTP Content-Disposition Explanation [ from MDN ]
    认证 (authentication) 和授权 (authorization) 的区别
    事件驱动引擎会取代多线程编程吗
    你所不知道的JSON
    都有哪些特殊而实用的的搜索引擎?
    巨头们的GitHub仓库整理
  • 原文地址:https://www.cnblogs.com/skyette/p/10700548.html
Copyright © 2020-2023  润新知