2011 Google Code Jam 小记
好久没写这种类型的代码,感觉真是退步了很多。 这是我第一次参加Google Code Jam,以前有过报名可是没有做过。 我发现Google Code Jam的题目使用经典算法的几乎没有,都是模拟或者数学题(起码我目前做过的几题是这样)
首先是Qualification Round 四道水题,前两道模拟,后两道数学推公式。 第三道是位运算的,第四道由于那天没空了就没做,反正分数够了,听人说也是推公式的水题。 题目链接:http://code.google.com/codejam/contest/dashboard?c=975485
// Qualification Round -- A
#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
namespace gcj {
using namespace std;
struct rebot {
int passTime;
int position;
};
queue<bool> all;
queue<int> qo, qb;
void solve () {
int t, n, pos, time, tt;
char rot;
scanf("%d", &t);
rebot o, b;
for (int i = 0; i < t; i ++) {
while(qo.empty() == false)
qo.pop();
while(qb.empty() == false)
qb.pop();
o.passTime = b.passTime = 0;
o.position = b.position = 1;
time = 0;
scanf("%d", &n);
while (n --) {
scanf(" %c %d", &rot, &pos);
bool isO = (rot == 'O');
all.push(isO);
if (isO)
qo.push(pos);
else
qb.push(pos);
}
while (all.size() > 0) {
bool isO = all.front();
all.pop();
if(isO) {
tt = max(0, abs(qo.front() - o.position) - o.passTime) + 1;
time += tt;
b.passTime += tt;
o.position = qo.front();
o.passTime = 0;
qo.pop();
} else {
tt = max(0, abs(qb.front() - b.position) - b.passTime) + 1;
time += tt;
o.passTime += tt;
b.position = qb.front();
b.passTime = 0;
qb.pop();
}
}
printf("Case #%d: %d\n", i + 1, time);
}
}
}
int main () {
freopen("d:/A-large.in", "r", stdin);
freopen("d:/A-large.out", "w", stdout);
gcj::solve();
return 0;
}然后是Round 1A 2011 状态不好,能力有限,我只看了第一和第二题 题目链接:http://code.google.com/codejam/contest/dashboard?c=1145485 第一题是告诉你一个今天最大比赛数量、今天胜率、总胜率,问数据是否可能达到. 我的想法是正确的,只有在计算符合今日胜率的最小局数和考虑总胜率为100和为0的情况即可,其他经过我简单的证明都是可行的,但是在获取最小的满足“今天胜率”的今日比赛数量的时候少打了一组括号,并且每注意到大数据范围到10^15,直接导致小数据PASS,大数据挂掉. 后来看了大牛的代码发现他用了最大公约数来解这个值,非常好。 贴小数据代码,大数据只要换到64位整数即可
第二题是猜字游戏 看了大牛的代码,用了DFS,两次精妙的索引排序解决了。太强大了,我还有差距呵。
然后是Round 1B 2011 题目链接:http://code.google.com/codejam/contest/dashboard?c=1150485 这个发挥得比较好,拿到了晋级名额。 我也只写了两道题,但是方法都对,而且都是1A,最后一道题我发现只剩下25分钟了,而且很晚了,反正写不完就懒得写了 第一题是模拟,按题目说的做就好了,这题在大数据的时候freopen的路径写错了,结果我一直在想为什么会TLE,还好在提交限时的两分钟前看到了,马上改掉就ok了。
第二题是一个数学题,又是数学题,问最少多久能让任意两个热狗店距离不小于d,计算的时候只要考虑往一个方向走,然后最后答案除以2即可,因为运动是对称的。中途需要考虑的是两个相邻组的距离问题,然后对分散时间进行合并取大值,并考虑交叉的情况加上分开交叉情况的时间即可。又是64位整形,不过这次我注意到了。不过那个maxn貌似我忘记改成大数据的数字了,为什么过了,神奇的。
Round2期间正碰上期末考试,但是我还是来做了一下,很失望的没拿到衣服。感觉我的编码能力还差得远呐,因为AC两题应该就能拿到衣服了,可是遗憾在第二题。 A很简单,大意是一个人在一条路上走,可以跑t秒,告诉走路和跑步的速度,再有的是路上有n个不重叠的walkway,在walkway上的速度等于walkway的速度+当前速度,问最少几秒钟到终点。思路非常简单,就是要在walkway上加速尽量多的时间。有两种情况,一种是在没有walkway的路上跑步跑完了t秒,这种情况时间很好算。另一种是walkway之外的路上t秒没用完,这时后要尽量在速度快的walkway上加速,所以对walkway的速度排序就可以了。需要注意的情况就是从头跑到尾的情况。 A题代码:
B题是我的痛啊,如果是难题,我不会,那我无话可说,关键是简单的计算几何+简单的DP,方法对,思路对,写代码的时候犯了N个白痴错误,各种变量名写错,各种复制代码忘了改。以后要注意写代码宁愿慢一点结构严谨,也不要贪图方便Copy代码。 比赛的时候这题我首先理解题目花了40多分钟,花了10分钟推导,50多分钟编码竟然都没写出来,Sample都没过,赛后我完全重写了一下,写出来到过小数据和大数据花了大概40分钟不到。真是不甘心。
B题大意是给一个矩形钢板,要求先裁出一块正方形,边长大于等于3,再去掉四个角,要求最终的东西重心在形状上的中心。问是否存在如果存在给出最大的第一次裁出的正方形边长。题目难理解的地方在于开始输入的有r c d,而给的每个grid的重量是d+wij,这个地方我一直没理解然后用sample测理解。方法就是DP,对R和C进行DP,对K枚举就好。需要注意的地方是k可以为偶数。 B题代码:
唉,真心还需要学习提高水平啊。
Last updated
Was this helpful?