zoukankan      html  css  js  c++  java
  • Google Code Jam Round 1A 2015 解题报告

    题目链接:https://code.google.com/codejam/contest/4224486/

    Problem A. Mushroom Monster

    这题题意就是,有N个时间点,每个时间点,Kaylin可以吃掉一定数量的mushroom,Bartholomew可以放入任意数量的mushroom。

    现在给出N个时间点分别有多少mushroom。

    问:若Kaylin每个时间点可以吃任意数量的mushroom,那为了配合每个时间点的mushroom,Kaylin最少要吃掉多少蘑菇。

    问:若Kaylin已恒定速度吃mushroom(即在每个时间点间吃的数量相同,若盘子空了则暂停进食),那为了配合每个时间点的mushroom,Kaylin最少要吃掉多少蘑菇。

    看懂题目就是水题,第一问,只要吃掉下一个时间点相对于当前时间点减少的mushroom数量。

    第二问,只要保证吃的速度要大于等于所有时间点mushroom减少的数量,即取需求速度最大值。

    代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <numeric>
     6 #include <queue>
     7 using namespace std;
     8 
     9 const int MAXN = 1010;
    10 const int INF = 0x3f3f3f3f;
    11 
    12 int a[MAXN], maxr[MAXN];
    13 int T, n;
    14 
    15 int solve1() {
    16     int res = 0;
    17     for(int i = 0; i < n - 1; ++i)
    18         res += max(0, a[i] - a[i + 1]);
    19     return res;
    20 }
    21 
    22 int solve2() {
    23     int spd = 0;
    24     for(int i = 0; i < n - 1; ++i)
    25         spd = max(spd, a[i] - a[i + 1]);
    26     int res = 0;
    27     for(int i = 0; i < n - 1; ++i)
    28         res += min(a[i], spd);
    29     return res;
    30 }
    31 
    32 int main() {
    33     freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    34     scanf("%d", &T);
    35     for(int t = 1; t <= T; ++t) {
    36         scanf("%d", &n);
    37         for(int i = 0; i < n; ++i)
    38             scanf("%d", &a[i]);
    39         maxr[n] = 0;
    40         for(int i = n - 1; i >= 0; --i)
    41             maxr[i] = max(maxr[i + 1], a[i]);
    42         printf("Case #%d: %d %d
    ", t, solve1(), solve2());
    43     }
    44 }
    View Code

    Problem B. Haircut

    题目大意:已知有B个理发师,和B个理发师给任意一个人理发所需要的时间。现在有N个人在排队,若处于队首,会找当前不是正在理发的编号最小的理发师理发。

    问:处于队列第N个的人会找第几个理发师。

    思路:二分时间 time,计算在time个单位时间里,有sum人已经或正在理发,又有cnt个理发师恰好没有正在理发的人。

    那么,若sum + cnt ≥ N,那么第N个人在前 time 个单位时间里,一定有机会开始理发。

    如此二分可以得到第N个人开始理发的时间,再由上述的sum、cnt可以得到第N个人让第几个理发师理发。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 typedef long long LL;
     7 
     8 const int MAXN = 1010;
     9 
    10 int a[MAXN];
    11 int T, n, b;
    12 
    13 bool check(LL k) {
    14     LL sum = 0, cnt = 0;
    15     for(int i = 0; i < b; ++i) {
    16         cnt += (k % a[i] == 0);
    17         sum += (k - 1) / a[i] + 1;
    18     }
    19     return sum + cnt >= n;
    20 }
    21 
    22 int solve() {
    23     LL l = 0, r = LL(n) * *max_element(a, a + b);//1000000;//
    24     while(l < r) {
    25         LL mid = (l + r) >> 1;
    26         if(!check(mid)) l = mid + 1;
    27         else r = mid;
    28     }
    29     LL sum = 0, p = 0;
    30     for(int i = 0; i < b; ++i)
    31         sum += (l - 1) / a[i] + 1;
    32     for(int i = 0; i < b; ++i)
    33         if(l % a[i] == 0 && sum + ++p == n) return i + 1;
    34     return -1;
    35 }
    36 
    37 int main() {
    38     freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    39     scanf("%d", &T);
    40     for(int t = 1; t <= T; ++t) {
    41         scanf("%d%d", &b, &n);
    42         for(int i = 0; i < b; ++i)
    43             scanf("%d", &a[i]);
    44         printf("Case #%d: %d
    ", t, solve());
    45     }
    46 }
    View Code

    Problem C. Logging

    给N个点,分别问对于每个点来说,至少删掉多少个点,能使该点在剩下的点的凸包的边上。

    思路1:因为凸包的边的性质是:对于一条边,每个点都在其同侧。那么,O(n^2)枚举所有边,O(n)枚举所有点,看要删掉那些点。复杂度O(n^3),可以跑过小数据,牛叉的电脑可以过大数据(RMB玩家与贫民玩家的区别就体现在这里了!)

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <vector>
     7 using namespace std;
     8 typedef long long LL;
     9 
    10 const int MAXN = 3010;
    11 
    12 struct Point {
    13     int x, y, id;
    14     Point() {}
    15     Point(int x, int y): x(x), y(y) {}
    16     void read(int i) {
    17         id = i;
    18         scanf("%d%d", &x, &y);
    19     }
    20     Point operator - (const Point &rhs) const {
    21         return Point(x - rhs.x, y - rhs.y);
    22     }
    23     bool operator < (const Point &rhs) const {
    24         if(y != rhs.y) return y < rhs.y;
    25         return x < rhs.x;
    26     }
    27 };
    28 
    29 LL cross(const Point &a, const Point &b) {
    30     return (LL)a.x * b.y - (LL)a.y * b.x;
    31 }
    32 //ret >= 0 means turn right
    33 LL cross(const Point &op, const Point &sp, const Point &ed) {
    34     return cross(sp - op, ed - op);
    35 }
    36 
    37 Point p[MAXN];
    38 int ans[MAXN];
    39 int n, top, T;
    40 
    41 void update_min(int &a, int b) {
    42     if(a > b) a = b;
    43 }
    44 
    45 void solve() {
    46     for(int i = 0; i < n; ++i) for(int j = i + 1; j < n; ++j) {
    47         int lsum = 0, rsum = 0;
    48         for(int k = 0; k < n; ++k) {
    49             LL t = cross(p[i], p[j], p[k]);
    50             if(t > 0) lsum++;
    51             if(t < 0) rsum++;
    52         }
    53         update_min(ans[i], min(lsum, rsum));
    54         update_min(ans[j], min(lsum, rsum));
    55     }
    56 }
    57 
    58 int main() {
    59     freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    60     scanf("%d", &T);
    61     for(int t = 1; t <= T; ++t) {
    62         scanf("%d", &n);
    63         for(int i = 0; i < n; ++i)
    64             p[i].read(i), ans[i] = n - 1;
    65         solve();
    66         printf("Case #%d:
    ", t);
    67         for(int i = 0; i < n; ++i)
    68             printf("%d
    ", ans[i]);
    69     }
    70 }
    View Code

    思路2:枚举每一个点,其他点绕枚举点排序,用一条过枚举点的直线旋转,计算要删掉的最少点。复杂度O(n^2logn)。

    代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <cmath>
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 struct Point {
    10     int x, y;
    11     Point() {}
    12     Point(int x, int y): x(x), y(y) {}
    13     Point operator - (const Point &rhs) const {
    14         return Point(x - rhs.x, y - rhs.y);
    15     }
    16     double ang() const {
    17         return atan2(y, x);
    18     }
    19     bool type() const {
    20         if(y != 0) return y > 0;
    21         return x < 0;
    22     }
    23 };
    24 
    25 LL cross(const Point &a, const Point &b) {
    26     return (LL)a.x * b.y - (LL)a.y * b.x;
    27 }
    28 
    29 const int MAXN = 3010;
    30 
    31 Point p[MAXN], v[MAXN << 1];
    32 int n, T;
    33 
    34 bool cmp(const Point &a, const Point &b) {
    35     if(a.type() != b.type()) return a.type() < b.type();
    36     return cross(a, b) > 0;
    37 }
    38 
    39 void solve(int n) {
    40     for(int i = 1; i < n; ++i)
    41         v[i - 1] = p[i] - p[0];
    42     n--;
    43     sort(v, v + n, cmp);
    44     copy(v, v + n, v + n);
    45     int res = 0;
    46     for(int i = 0, j = 0; i < n; ++i) {
    47         if(i == j) j++;
    48         while(j < i + n && cross(v[i], v[j]) >= 0) ++j;
    49         res = max(res, j - i);
    50     }
    51     printf("%d
    ", n - res);
    52 }
    53 
    54 int main() {
    55     freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    56     scanf("%d", &T);
    57     for(int t = 1; t <= T; ++t) {
    58         scanf("%d", &n);
    59         for(int i = 0; i < n; ++i)
    60             scanf("%d%d", &p[i].x, &p[i].y);
    61         printf("Case #%d:
    ", t);
    62         for(int i = 0; i < n; ++i) {
    63             swap(p[0], p[i]);
    64             solve(n);
    65             swap(p[0], p[i]);
    66         }
    67     }
    68 }
    View Code
  • 相关阅读:
    ID控制tab切换
    jQuery控制图片的hover效果
    popup效果
    第一篇博客
    Java面试中hashCode()与equals(Object obj)方法关系的准确回答
    小福bbs凡事预则立
    编译cppunit
    EasyUI Datagrid数据网格
    发送邮件
    京东笔试
  • 原文地址:https://www.cnblogs.com/oyking/p/4447024.html
Copyright © 2011-2022 走看看