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\n", 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\n", 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:\n", t); 67 for(int i = 0; i < n; ++i) 68 printf("%d\n", 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", 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:\n", 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?
轉載于:https://www.cnblogs.com/oyking/p/4447024.html
總結
以上是生活随笔為你收集整理的Google Code Jam Round 1A 2015 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于手思3.0 代码规范
- 下一篇: 笔谈OpenGL ES(一)