google kcikstart 2018 round c

https://code.google.com/codejam/contest/4384486/dashboard#s=p0

A

题意

给定一个无向图,其中存在着唯一的一个环,求每个点到这个环的最短距离。

数据范围

≤ T ≤ 100.

1 ≤ xi ≤ N, for all i.

1 ≤ yi ≤ N, for all i.

xi ≠ yi, for all i.

(xi, yi) ≠ (xj, yj), for all i ≠ j.

The graph in which planets are nodes and tubes are edges is connected and has exactly one cycle.

small

3 ≤ N ≤ 30.

large

3 ≤ N ≤ 1000.

题解

显然关键在于找出这个环上的点。找出之后即使是大数据集也可以暴力BFS遍历每个点到这个换的最短距离(O(n^2)),或者可以反过来从环上bfs到所有点(O(n))。

比较暴力的找环方法是直接DFS遍历,然后list存储走过的点,当点的所有child dfs完之后将该点删掉。这样遇到重复的点时这之间的所有点就是该环。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
vector<int> g[1005];
vector<int> path;
vector<int> circle;
bool visited[1005];
void dfs(int cur, int pa) {
    if (visited[cur] == true) {
        auto it = find(path.begin(), path.end(), cur);
        if (it != path.end()) {
            while (it != path.end()) {
                circle.push_back(*it);
                it++;
            }
        }
        return;
    }
    visited[cur] = true;
    path.push_back(cur);
    for (int &child : g[cur]) {
        if (child != pa) {
            dfs(child, cur);
        }
    }
    path.pop_back();
}
void solve() {
    int n;
    cin >> n;
    int x, y;
    for (int i = 1; i <= n; i++) {
        g[i].clear();
    }
    path.clear();
    circle.clear();
    memset(visited, false, sizeof(visited));
    for (int i = 1; i <= n; i++) {
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs(1, -1);
    vector<int> dis(n+1, n+1);
    queue<int> q;
    int temp = circle.size();
    for (int i = 0; i < temp; i++) {
        //cout << circle[i] << "\n";
        dis[circle[i]] = 0;
        q.push(circle[i]);
    }
    int cur = 1;
    while (!q.empty()) {
        int sz = q.size();
        for (int i = 0; i < sz; i++) {
            int top = q.front();
            q.pop();
            for (int &child : g[top]) {
                if (dis[child] > cur) {
                    dis[child] = cur;
                    q.push(child);
                }
            }
        }
        cur++;
    }
    printf("%d",dis[1]);
    for (int i = 2; i <= n; i++) {
        printf(" %d", dis[i]);
    }
    printf("\n");
}
int main() {
    freopen("A-large.in", "r", stdin);
    freopen("A-large.out", "w", stdout);
    int t;
    cin >> t;
    for (int tt = 1; tt <= t; tt++) {
        printf("Case #%d: ", tt);
        solve();
    }
    return 0;
}

B

题意

求从一个无向图中拆出的边能组成的凸边形个数。其中拆出的便不能有相同的端点。

数据范围

0 ≤ Li, j ≤ 1000 for all i, j.

Li, i = 0, for all i.

Li, j = Lj, i, for all i, j.

small

N = 6

large

6<=N<=15

题解

对小数据集,显然最多只能拆出三条边组成三角形,暴力即可。

大数据集不会,待补。

C

题意

给一个数组,对数组中的所有连续子数组按以下公式求k次和,然后求和最后所有的结果(modulo 1000000007)。

对连续子数组Aj, Aj+1, ..., Ak,第i次求和公式为 Aj × 1i + Aj+1 × 2i + Aj+2 × 3i + ... + Ak × (k-j+1)i.

样例:

In Sample Case #1, the Parameter Array is [3, 2]. All the contiguous subarrays are [3], [2], [3, 2].

For i = 1:

1-st Exponential-power of [3] = 3 × 11 = 3

1-st Exponential-power of [2] = 2 × 11 = 2

1-st Exponential-power of [3, 2] = 3 + 2 × 21 = 7

So POWER1 is 12.

For i = 2:

2-nd Exponential-power of [3] = 3 × 12 = 3

2-nd Exponential-power of [2] = 2 × 12 = 2

2-nd Exponential-power of [3, 2] = 3 + 2 × 22 = 11

So POWER2 is 16.

For i = 3:

3-rd Exponential-power of [3] = 3 × 13 = 3

3-rd Exponential-power of [2] = 2 × 13 = 2

3-rd Exponential-power of [3, 2] = 3 + 2 × 23 = 19

So POWER3 is 24.

So answer is 24 + 12 + 16 = 53.

数据范围

1 ≤ T ≤ 100.

1 ≤ x1 ≤ 1e5.

1 ≤ y1 ≤ 1e5

1 ≤ C ≤ 1e5.

1 ≤ D ≤ 1e5.

1 ≤ E1 ≤ 1e5.

1 ≤ E2 ≤ 1e5.

1 ≤ F ≤ 1e5.

small

1 ≤ N ≤ 100.

1 ≤ K ≤ 20.

large

1 ≤ N ≤ 1e6.

1 ≤ K ≤ 1e4

题解

首先根据xycdef生成数组A。

对于小数据集暴力即可。O(k*n^3)

对于大数据集,可以考虑每个数对最后结果的贡献,大力推推就可以出来了。

考虑第i次计算,则数组A中第j位计算的值为:A[j] * (N+1-j) * {1^i + 2^i + .... + j^i} ( j从1开始) 。直接枚举的话复杂度O(k * n^2lgk) ,当然第j^i求和可以累加,能降到O(knlgk) 。

另一种思路是调换一下求和顺序,则ans=sum_{i=1..j} {A[j] (N+1-j) * sum_{i=1..k}{1^i + 2^i + .... + j^i}}。其中m^i求和可以用等比数列公式,再通过累加可以降到O(k*lgk)。(lgk为求幂时的复杂度)

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9 + 7;
ll pw(ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b&1) ans = ans * a % mod;
        b /= 2;
        a = a * a % mod;
        //cout << ans << " " << a << "\n";
    }
    return ans;
}
ll calc(ll a, ll b) {
    //cout << pw(a, b) << "\n";
    ll ans = a * ((pw(a, b) - 1 + mod) % mod) % mod * pw(a-1, mod-2) % mod;
    //cout << ans <<"\n";
}
ll solve() {
    ll n, k;
    cin >> n >>k;
    vector<ll> nums(n+1);
    ll x, y;
    cin >> x >> y;
    ll c,d,e1,e2,f;
    cin >> c >> d >> e1 >> e2 >> f;
    nums[1] = (x+y) % f;
    for (int i = 2; i <= n; i++) {
        ll tx = x, ty = y;
        x = (c*tx+d*ty+e1) %f;
        y = (d*tx+c*ty+e2) %f;
        nums[i] = (x+y) % f;
    }
    ll ans = nums[1]*n%mod*k%mod;
    ll sum = k;
    //cout << ans <<"\n";
    for (int i = 2; i <= n; i++) {
        sum = (sum + calc(i, k)) % mod;
        //cout << sum << "\n";
        ans = (ans + nums[i] * (n+1-i) % mod * sum % mod) % mod;
        //cout << i << " " << ans << "\n";
    }
    return ans;
}
int main() {
    freopen("C-large-practice.in", "r", stdin);
    freopen("C-large.out", "w", stdout);
    int t;
    cin >> t;
    for (int tt = 1; tt <= t; tt++) {
        std::cerr << tt << "\n";
        printf("Case #%d: %lld\n", tt, solve());
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hxidkd/p/9181100.html

时间: 2024-10-09 17:42:18

google kcikstart 2018 round c的相关文章

人气爆棚!Google DevFest 2018广州国际嘉年华为什么这么火?

12月23日,"Google DevFest 2018 广州国际嘉年华"在广州·珠江琶醍媒棚举行.集合Google .Linux基金会.世界银行.美国科学院.中科院.BAT等知名科技互联网公司和开源世界里优秀的人工智能.Flutter.大数据.云计算.Android以及区块链等技术领域的大咖,给开发者和科技爱好者们带来了最高质量的演讲和丰富的现场体验项目. 闯客网CEO战辰作为活动联合承办方出席了本次活动,并联合AIOT科技节发起方:谷歌开发者社区广州负责人唐松龙.英唐集团副总裁陈正亮

【二分答案】Google Code Jam Round 1A 2018

题意:有R个机器人,去买B件商品,有C个收银员,每个收银员有能处理的商品数量上限mi,处理单件商品所需的时间si,以及最后的装袋时间pi. 每个收银员最多只能对应一个机器人,每个机器人也最多只能对应一个收银员. 让你给每个机器人安排他购买的商品数,以及对应哪个机器人,问你最少需要多长时间才能买回所有商品. 二分答案lim,将收银员按照min(m[i],(lim-p[i])/s[i])(此即为该收银员在当前限制下能处理的商品数)从大到小排序,贪心加入,看是否满足即可. #include<cstdi

Google Kick Start 2018 Round C Planet Distance

思想: 1.用邻接表建图. 2.建完图之后,先把图中的环给找出来. 怎么找呢? (1)先统计每一个节点的度.   (2)统计完了之后,通过使用队列,把度为1 的点给剔除.每剔除一个,所谓剔除其实就是用一个dis[] 数组来做标记,其相应的邻居的度减一,如果该邻居的度为1了,那么把它加到队列里,重复上述过程,直到队列为空. (3)最后统计一下,剩下的就是环里的元素. 3.再对环里的元素用BFS搞一下,往外扩散.记录距离. AC 代码如下: import java.util.ArrayList; i

【Kickstart】2018 Round (Practice ~ H)

Practice Round Problem A GBus count (9pt/15pt) (2019年1月14日,kickstart群每日一题) 题意:有一条笔直的大路,上面有城市编号从 1 开始从左到右一次排列.上面有 N 个 GBuses, 每一个 bus[i] 连接 A[i]  到 B[i] 两个地点(包含这两个地方).我们想要求 P 个城市,每个城市经过的公交车数量. 输入输出 和 数据规模 如下: There exist some cities that are built alo

Google Kickstart 2020 Round A: Plates Solution

Problem Statement Problem Dr. Patel has N stacks of plates. Each stack contains K plates. Each plate has a positive beauty value, describing how beautiful it looks. Dr. Patel would like to take exactly P plates to use for dinner tonight. If he would

google code jam Round 1A 2015 Problem C. Logging

Problem A certain forest consists of N trees, each of which is inhabited by a squirrel. The boundary of the forest is the convex polygon of smallest area which contains every tree, as if a giant rubber band had been stretched around the outside of th

Google codejam Qualification Round 2015 B 巧妙枚举结果 + 贪心

背景:想了好久只想到用深搜的指数级别枚举办法来过了小数据,大数据自然超时,后来看了解题报告,才过. 思路:当前所有盘子中,煎饼个数最多的盘子里有n个煎饼,i 从 1 - n 枚举分裂之后的煎饼最多盘子里的个数,然后用贪心的方法计算要达到当前状态所需的最少分裂步数 k ,最后用时就是 i + k ,求出所有用时中最小的即可 感悟:这个题的精华之处是所有最终状态最多只有1000种,对于每种最终状态所需要的的步数又可以通过高效的贪心方法求出,思维很巧妙,算是暴力枚举和贪心的巧妙结合. 我的代码: #i

Google Code Jam Round 1A 2015 Problem B. Haircut 二分

Problem You are waiting in a long line to get a haircut at a trendy barber shop. The shop has B barbers on duty, and they are numbered 1 through B. It always takes the kth barber exactly Mk minutes to cut a customer's hair, and a barber can only cut

Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)C. Producing Snow+差分标记

题目链接:C. Producing Snow 题意:给两个数组v[N],T[N],v[i]表示第i天造的雪,T[i],表示第i天的温度,一堆雪如果<=T[i],当天就会融完,否则融化T[i],要求输出每天的融雪总量. 题解:我对T数组求个前缀和,就可以二分找到每堆雪在那一天(pos)融化,余下的要加进答案中ans[i],然后用一个an数组在a[i]+1,a[pos]-1,最后求再求一次前缀和. ans[i]再加上an[i]*t[i].每次操作二分logn,N次操作.复杂度O(nlogn) #in