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减少的数量,即取需求速度最大值。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <numeric>
#include <queue>
using namespace std; const int MAXN = ;
const int INF = 0x3f3f3f3f; int a[MAXN], maxr[MAXN];
int T, n; int solve1() {
int res = ;
for(int i = ; i < n - ; ++i)
res += max(, a[i] - a[i + ]);
return res;
} int solve2() {
int spd = ;
for(int i = ; i < n - ; ++i)
spd = max(spd, a[i] - a[i + ]);
int res = ;
for(int i = ; i < n - ; ++i)
res += min(a[i], spd);
return res;
} int main() {
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d", &n);
for(int i = ; i < n; ++i)
scanf("%d", &a[i]);
maxr[n] = ;
for(int i = n - ; i >= ; --i)
maxr[i] = max(maxr[i + ], a[i]);
printf("Case #%d: %d %d\n", t, solve1(), solve2());
}
}
Problem B. Haircut
题目大意:已知有B个理发师,和B个理发师给任意一个人理发所需要的时间。现在有N个人在排队,若处于队首,会找当前不是正在理发的编号最小的理发师理发。
问:处于队列第N个的人会找第几个理发师。
思路:二分时间 time,计算在time个单位时间里,有sum人已经或正在理发,又有cnt个理发师恰好没有正在理发的人。
那么,若sum + cnt ≥ N,那么第N个人在前 time 个单位时间里,一定有机会开始理发。
如此二分可以得到第N个人开始理发的时间,再由上述的sum、cnt可以得到第N个人让第几个理发师理发。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL; const int MAXN = ; int a[MAXN];
int T, n, b; bool check(LL k) {
LL sum = , cnt = ;
for(int i = ; i < b; ++i) {
cnt += (k % a[i] == );
sum += (k - ) / a[i] + ;
}
return sum + cnt >= n;
} int solve() {
LL l = , r = LL(n) * *max_element(a, a + b);//1000000;//
while(l < r) {
LL mid = (l + r) >> ;
if(!check(mid)) l = mid + ;
else r = mid;
}
LL sum = , p = ;
for(int i = ; i < b; ++i)
sum += (l - ) / a[i] + ;
for(int i = ; i < b; ++i)
if(l % a[i] == && sum + ++p == n) return i + ;
return -;
} int main() {
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d%d", &b, &n);
for(int i = ; i < b; ++i)
scanf("%d", &a[i]);
printf("Case #%d: %d\n", t, solve());
}
}
Problem C. Logging
给N个点,分别问对于每个点来说,至少删掉多少个点,能使该点在剩下的点的凸包的边上。
思路1:因为凸包的边的性质是:对于一条边,每个点都在其同侧。那么,O(n^2)枚举所有边,O(n)枚举所有点,看要删掉那些点。复杂度O(n^3),可以跑过小数据,牛叉的电脑可以过大数据(RMB玩家与贫民玩家的区别就体现在这里了!)
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL; const int MAXN = ; struct Point {
int x, y, id;
Point() {}
Point(int x, int y): x(x), y(y) {}
void read(int i) {
id = i;
scanf("%d%d", &x, &y);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
bool operator < (const Point &rhs) const {
if(y != rhs.y) return y < rhs.y;
return x < rhs.x;
}
}; LL cross(const Point &a, const Point &b) {
return (LL)a.x * b.y - (LL)a.y * b.x;
}
//ret >= 0 means turn right
LL cross(const Point &op, const Point &sp, const Point &ed) {
return cross(sp - op, ed - op);
} Point p[MAXN];
int ans[MAXN];
int n, top, T; void update_min(int &a, int b) {
if(a > b) a = b;
} void solve() {
for(int i = ; i < n; ++i) for(int j = i + ; j < n; ++j) {
int lsum = , rsum = ;
for(int k = ; k < n; ++k) {
LL t = cross(p[i], p[j], p[k]);
if(t > ) lsum++;
if(t < ) rsum++;
}
update_min(ans[i], min(lsum, rsum));
update_min(ans[j], min(lsum, rsum));
}
} int main() {
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d", &n);
for(int i = ; i < n; ++i)
p[i].read(i), ans[i] = n - ;
solve();
printf("Case #%d:\n", t);
for(int i = ; i < n; ++i)
printf("%d\n", ans[i]);
}
}
思路2:枚举每一个点,其他点绕枚举点排序,用一条过枚举点的直线旋转,计算要删掉的最少点。复杂度O(n^2logn)。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL; struct Point {
int x, y;
Point() {}
Point(int x, int y): x(x), y(y) {}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
double ang() const {
return atan2(y, x);
}
bool type() const {
if(y != ) return y > ;
return x < ;
}
}; LL cross(const Point &a, const Point &b) {
return (LL)a.x * b.y - (LL)a.y * b.x;
} const int MAXN = ; Point p[MAXN], v[MAXN << ];
int n, T; bool cmp(const Point &a, const Point &b) {
if(a.type() != b.type()) return a.type() < b.type();
return cross(a, b) > ;
} void solve(int n) {
for(int i = ; i < n; ++i)
v[i - ] = p[i] - p[];
n--;
sort(v, v + n, cmp);
copy(v, v + n, v + n);
int res = ;
for(int i = , j = ; i < n; ++i) {
if(i == j) j++;
while(j < i + n && cross(v[i], v[j]) >= ) ++j;
res = max(res, j - i);
}
printf("%d\n", n - res);
} int main() {
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d", &n);
for(int i = ; i < n; ++i)
scanf("%d%d", &p[i].x, &p[i].y);
printf("Case #%d:\n", t);
for(int i = ; i < n; ++i) {
swap(p[], p[i]);
solve(n);
swap(p[], p[i]);
}
}
}
Google Code Jam Round 1A 2015 解题报告的更多相关文章
- 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 barb ...
- Google Code Jam Round 1C 2015 Problem A. Brattleship
Problem You're about to play a simplified "battleship" game with your little brother. The ...
- [Google Code Jam (Round 1A 2008) ] A. Minimum Scalar Product
Problem A. Minimum Scalar Product This contest is open for practice. You can try every problem as ...
- 【二分答案】Google Code Jam Round 1A 2018
题意:有R个机器人,去买B件商品,有C个收银员,每个收银员有能处理的商品数量上限mi,处理单件商品所需的时间si,以及最后的装袋时间pi. 每个收银员最多只能对应一个机器人,每个机器人也最多只能对应一 ...
- 【贪心】Google Code Jam Round 1A 2018 Waffle Choppers
题意:给你一个矩阵,有些点是黑的,让你横切h刀,纵切v刀,问你是否能让切出的所有子矩阵的黑点数量相等. 设黑点总数为sum,sum必须能整除(h+1),进而sum/(h+1)必须能整除(v+1). 先 ...
- [C++]Store Credit——Google Code Jam Qualification Round Africa 2010
Google Code Jam Qualification Round Africa 2010 的第一题,很简单. Problem You receive a credit C at a local ...
- Google Code Jam Africa 2010 Qualification Round Problem B. Reverse Words
Google Code Jam Africa 2010 Qualification Round Problem B. Reverse Words https://code.google.com/cod ...
- Google Code Jam Africa 2010 Qualification Round Problem A. Store Credit
Google Code Jam Qualification Round Africa 2010 Problem A. Store Credit https://code.google.com/code ...
- Google Code Jam 2010 Round 1C Problem A. Rope Intranet
Google Code Jam 2010 Round 1C Problem A. Rope Intranet https://code.google.com/codejam/contest/61910 ...
随机推荐
- [转]Travis Ci的最接底气的中文使用教程
相信大家对Travis Ci已经不再陌生了,Github上已经有大部分的项目已经采用了它. Travis Ci是一个基于晕的持续集成项目,目前已经支持大部分主流语言了,如:C.PHP.Ruby.Pyt ...
- Skype无法收发组消息
我用微软账户登录的Skype 发现无法收发组消息 - 提示发送消息不可用 卸了重装 - 提示 "无法发送消息, 请尝试获取最新的消息版本, 或者是组内成员使用旧版本无法同时视频和发送 ...
- Fouandation(NSString ,NSArray,NSDictionary,NSSet) 中常见的理解错误区
Fouandation 中常见的理解错误区 1.NSString //快速创建(实例和类方法) 存放的地址是 常量区 NSString * string1 = [NSString alloc]init ...
- Java关键字
Java关键字简介 类别 关键字 说明 访问控制 private 私有的 protected 受保护的 public 公共的 类.方法和变量修饰符 abstract 声明抽象 class 类 exte ...
- (转)基于socket的TCP和UDP编程
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- php bmp中创建图像bmp2gd,让GD支持32位BMP
php GD库可方便的从URL新建一图像, GD中有imagecreatefromjpeg(),imagecreatefromPNG()....等之类的FUNCTION 可有时从URL中读取的切BMP ...
- <四>JDBC_PreparedStatement的使用
WHY? <1>使用Statement需要进行拼写SQL语句,容易出错; <2>PreparedStatement:是Statement的子接口,可以传入带占位符的SQL语句, ...
- Python实战:下载鬼灵报告有声小说
在家无聊,想看看小说,不过看的眼睛痛,就想着下个有声小说来听听.但风上找到的都是要一集一集下,还得重命名,122集啊,点到什么时候. 写个批处理下载的脚本.记录下过程. 一.老套路了,找到下载URL. ...
- JavaScript:数组大全
栈/队列 数组es3: pop删除最后一项(栈) shift删除第一项(队列) push增加到最后(栈) unshift增加到最前(队列) reverse翻转 join转字符串 slice截取(切片) ...
- htmlentities,html_entity_decode,addslashes
PHP htmlspecialchars_decode() 函数 PHP htmlspecialchars() 函数 PHP html_entity_decode() 函数 PHP中混淆的三组函数总结 ...