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\n", 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  */

B. Golf Gophers

题意:

思路:设所求的人数为TARGET。我们可以把18个计数器弱化为1个计数器,具体就是每个计数器的值都设为同一个,计作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, " \n"[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 }

C. Pylons

题意:

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

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

原文地址:https://www.cnblogs.com/skyette/p/10700548.html

时间: 2024-09-29 08:41:37

Google Code Jam 2019 Round 1A 题解的相关文章

Google Code Jam 2015 Round 1A Mushroom Monster 水

题意:每10秒扫描一下盘子,查看盘子里面的面包个数,问你主角用两种吃法可能吃得的最少的面包. 1)任意吃. 2)每秒以恒定速度. 解题思路:暴力,找差值. 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月18日 星期六 09时52分04秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #includ

Google Code Jam 2015 Round 1A Haircut 二分

题意:给你每个理发师的理发时间,问你排在队列中的第N个位置,问你应该被哪个理发师剪发. 解题思路:二分时间,看这个时间到第几个人理发了,然后找到临界值,看这个值的时候有那些理发师接待了新旅客的,即可找到那个理发师. 解题代码: 1 // File Name: b.sample.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月18日 星期六 09时05分30秒 4 5 #include<vector> 6 #include<lis

Google Code Jam 2009, Round 1C C. Bribe the Prisoners (记忆化dp)

Problem In a kingdom there are prison cells (numbered 1 to P) built to form a straight line segment. Cells number i and i+1 are adjacent, and prisoners in adjacent cells are called "neighbours." A wall with a window separates adjacent cells, and

Google Code Jam 2014 Round 2回顾和分析

回顾 比赛开始网络就一直在抽风,不知道宿舍网渣还是有人攻击服务器.刷了n遍n久刷出了题目.提交A小case的时候眼睁睁看着时间过去,却提交不上,这破网.最后A题B题还是解决了,C题扫了一眼,读都没读,就奔D题去了,因为我看到了熟悉的trie这个单词,加之看到小case只有9分,判断小case应该比较容易.前面因为网络浪费了很多时间,加之从未编过trie的程序,只能临时上网翻书去学,最后D小这个可以很容易暴力解的问题也没编完. 最终的rank是13xx,考虑到在这次GCJ之前从未接触过编程竞赛,而

Google Code Jam 2014 Round 1B Problem B

二进制数位DP,涉及到数字的按位与操作. 查看官方解题报告 #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> using namespace std; #define MAX_LEN 50 long long A, B, K; int a[MAX_LEN], b[MAX_LEN], k[MAX_LEN]; long long memoize[MAX_LEN]

Google Code Jam 2016 Round 1B B

题意:给出两个数字位数相同,分别中间有若干位不知道,用问号表示.现在要求补全这两个数字,使得差值的绝对值最小,多解则取第一个数字的值最小的,再多解就取第二个数字最小的. 分析: 类似数位dp,但是很多状态可以直接得出最终解,个别状态需要状态转移. 我们从高位到低位依次确定两个数的每个位是几.一旦确定了两个数的一个位不一样,则可以立即将小的一方的后续问号全部写9,大的一方后续问号全部写0.这样才能让差值最小. 那我们观察每个位的时候要如何确定其值呢?分如下几种情况. 1.两个数的该位都是问号,那么

Google Code Jam 2016 Round 1C C

题意:三种物品分别有a b c个(a<=b<=c),现在每种物品各选一个进行组合.要求每种最和最多出现一次.且要求任意两个物品的组合在所有三个物品组合中的出现总次数不能超过n. 要求给出一个方案,使得我们能够生成的组合数最多. 分析: 首先我们可以简单的处理一种情况,就是c<=n的情况. 因为我们枚举出了所有组合,那么两物品的出现次数的最大值不会超过c,因为A种和B种的每对组合都会在其中出现c次,其余两个的组合出现次数更少. 所以这种情况一定不会超过n,我们只需要枚举所有组合即可. 然而

2015 Google code jam Qualification Round B 枚举 + 贪心

题意:给你一个无穷长的数列 和一些非 0 的值,可以进行两种操作. 1)数列中所有大于1的值 都减1 2)从 a[i] 中取出任意的值分给任意人. 问你最少执行多少步能使的 数列全为0. 解题思路:枚举最大的a[i].大于 a[i]的部分都分出去. 解题代码: 1 // File Name: b.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月11日 星期六 23时16分58秒 4 5 #include<vector> 6 #incl

2015 Google code jam Qualification Round A 水

题意:给你一个序列 从 0-n  初始位置为0 ,只能从 i 走到 i+1  你必要有的人数 >= i+1  ,每个位置有a[i]个人,问你走到 n 还需要多少个人. 解题思路:暴力 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月11日 星期六 23时06分57秒 4 5 #include<vector> 6 #include<list> 7 #include<