OWenT's blog
  • Introduction
  • About Me
  • 2020
    • 近期对libatapp的一些优化调整(增加服务发现和连接管理,支持yaml等)
    • xresloader转表工具链增加了一些新功能(map,oneof支持,输出矩阵,基于模板引擎的加载代码生成等)
    • 在游戏服务器中使用分布式事务
    • libcopp接入C++20 Coroutine和一些过渡期的设计
    • libatbus 的大幅优化
    • nftables初体验
    • 容器配置开发环境小计
  • 2019
    • PALM Tree - 适合多核并发架构的B+树 - 论文阅读小记
    • 跨平台协程库 - libcopp 简介
    • C++20 Coroutine 性能测试 (附带和libcopp/libco/libgo/goroutine/linux ucontext对比)
    • 尝鲜Github Action
    • 一些xresloader(转表工具)的改进
    • protobuf、flatbuffer、msgpack 针对小数据包的简单对比
    • 协程框架(libcopp) 小幅优化
    • Excel转表工具(xresloader) 增加protobuf插件功能和集成 UnrealEngine 支持
    • Anna(支持任意扩展和超高性能的KV数据库系统)阅读笔记
    • C++20 Coroutine
    • libcopp merge boost.context 1.69.0
    • Google去中心化分布式系统论文三件套(Percolator、Spanner、F1)读后感
    • Rust玩具-企业微信机器人通用服务
  • 2018
    • 使用ELK辅助监控开发测试环境服务质量和问题定位
    • Webpack+vue+boostrap+ejs构建Web版GM工具
    • 2018年的新通用伪随机数算法(xoshiro / xoroshiro)的C++(head only)实现
    • Rust的第二次接触-写个小服务器程序
    • 理解和适配AEAD加密套件
    • atsf4g-co的进化:协程框架v2、对象路由系统和一些其他细节优化
    • 协程框架(libcopp)v2优化、自适应栈池和同类库的Benchmark对比
    • 可执行文件压缩
    • 初识Rust
    • 使用restructedtext编写xresloader文档
    • atframework的etcd模块化重构
    • C++的backtrace
  • 2017
    • ECDH椭圆双曲线(比DH快10倍的密钥交换)算法简介和封装
    • protobuf-net的动态Message实现
    • pbc的proto3接入
    • atgateway内置协议流程优化-加密、算法协商和ECDH
    • 整理一波软件源镜像同步工具+DevOps工具
    • Blog切换到Hugo
    • libcopp v2的第一波优化完成
    • libcopp(v2) vs goroutine性能测试
    • libcopp的线程安全、栈池和merge boost.context 1.64.0
    • GCC 7和LLVM+Clang+libc++abi 4.0的构建脚本
    • libatbus的几个藏得很深的bug
    • 用cmake交叉编译到iOS和Android
    • 开源项目得一些小维护
    • atapp的c binding和c#适配
    • 对象路由系统设计
    • 2016年总结
    • 近期的一个协程流程BUG
  • 2016
    • 重写了llvm+clang+libc++和libc++abi的构建脚本
    • atsf4g完整游戏工程示例
    • atframework基本框架已经完成
    • 游戏服务器的不停服更新
    • 对atbus的小数据包的优化
    • Android和IOS的TLS问题
    • pbc的一个陈年老BUG
    • boost.context-1.61版本的设计模型变化
    • 接入letsencrypt+全面启用HTTP/2
    • 理解Raft算法
    • libatbus基本功能及单元测试终于写完啦
    • 博客文章和文档迁移到gitbook
  • 2015
    • 博客文章和文档迁移到gitbook
    • 给客户端写得LRU缓存
    • 近期活动比较零散
    • 关于BUS通信系统的一些思考(三)
    • 针对Java JIT的优化(转表工具:xresloader)
    • libcopp更新 (merge boost 1.59 context)
    • 小记最近踩得两个C++坑
    • Redis全异步(HA)Driver设计稿
    • Vim常用命令
    • 关于firewalld和systemd的一些命令速记
    • Jenkins(hudson)插件记录
    • 我们的Lua类绑定机制
    • LLVM+Clang+Libcxx+Libcxxabi(3.6)工具链编译(完成自举编译)
    • 回顾2014
    • Android NDK undefined reference to ___tls_get_addr 错误
    • gitlab腾讯企业邮箱配置
  • 2014
    • 回顾2013
    • C++11动态模板参数和type_traits
    • C++又一坑:动态链接库中的全局变量
    • tolua++内存释放坑
    • [转]类似github的框架
    • Lua性能分析
    • 集成Qt Webkit 到cocos2d-x
    • Gitlab环境搭建小计
    • 近期研究VPN的一些记录(OpenVPN,pptp,l2tp)
    • LLVM + Clang + Libcxx + Libcxxabi 工具链编译
    • 关于BUS通信系统的一些思考(二)
    • 关于BUS通信系统的一些思考(一)
    • [libiniloader] Project
    • 记录一些在线编辑器
    • [WP Code Highlight.js] Project
    • 再议 C++ 11 Lambda表达式
    • 基于Chrome插件的开发工具链
    • [ACM] HDU 1006 解题报告
    • Linux 编译安装 GCC 4.9
    • 又碰到了这个解谜游戏,顺带记下地址
    • 简单C++单元测试框架(支持一键切到GTest或Boost.Test)
    • 捣鼓一个协程库
  • 2013
    • std和boost的function与bind实现剖析
    • 不知道是哪一年的腾讯马拉松题目 照片评级 解题报告
    • Lua 挺好用的样子
    • VC和GCC成员函数指针实现的研究(三)
    • VC和GCC成员函数指针实现的研究(二)
    • VC和GCC内成员函数指针实现的研究(一)
    • 一个C++关于成员变量偏移地址的小Trick
    • ptmalloc,tcmalloc和jemalloc内存分配策略研究
    • POJ 2192 Zipper HDU 2059 龟兔赛跑
    • 从Javascript到Typescript到Node.js
    • 网络编程小结
    • 试试Boost.Asio
    • Lnmp yum 安装脚本 (for CentOS)
    • ARM 交叉编译环境搭建
    • Linux 编译安装 GCC 4.8
    • [记录]虚拟硬盘的压缩|磁盘写零
  • 2012
    • Boost.Spirit 初体验
    • “C++的90个坑”-阅读笔记
    • AC自动机
    • C++ 标准过渡期
    • 程序员修炼之道 -- 阅读笔记
    • [转载]狼与哈士奇
    • C++ 新特性学习(八) — 原子操作和多线程库[多工内存模型]
    • C++ 新特性学习(七) — 右值引用
    • 理解Protobuf的数据编码规则
    • 忆往昔ECUST的ACM时代
    • Linux编译安装GCC 4.7
    • JSON显示库 -- showJson (Javascript)
    • C++ 新特性学习(六) — 新的字符串编码和伪随机数
    • C++ 新特性学习(五) — 引用包装、元编程的类型属性和计算函数对象返回类型
    • C++ 新特性学习(四) — Bind和Function
  • 2011
    • C++ 新特性学习(三) — Regex库
    • C++ 新特性学习(二) -- Array、Tuple和Hash库
    • C++ 新特性学习(一) -- 概述+智能指针(smart_ptr)
    • Linux 和 Windows PowerShell 常用工具/命令 记录
    • 非常帅气的Linq to sql
    • 2011 Google Code Jam 小记
    • C++总是很神奇
    • 大学生创新项目[国家级]经费使用记录
    • 常用官方文档整理
    • 我们学校的IPV6很不错嘛
  • 2010
    • 线段树相关问题 (引用 PKU POJ题目) 整理
    • 2010 ACM 赛前笔记
    • POJ PKU 2596 Dice Stacking 解题报告
    • POJ PKU 3631 Cuckoo Hashing 解题报告
    • POJ PKU 1065 Wooden Sticks 3636 Nested Dolls 解题报告
    • HDU 3336 Count the string 解题报告
    • Hash模板 个人模板
    • ZOJ 3309 Search New Posts 解题报告
    • POJ PKU Let's Go to the Movies 解题报告
    • 注册表常用键值意义
    • PKU POJ 1724 ROADS 解题报告
    • 《神奇古今秘方集锦》&《民间秘术大全》
    • PKU POJ 1720 SQUARES 解题报告
    • POJ PKU 2155 Matrix 解题报告
    • PKU POJ 1141 Brackets Sequence 解题报告
    • PKU POJ 2728 Desert King 解题报告
    • PKU POJ 2976 Dropping tests 解题报告
    • PKU POJ 3757 Simple Distributed storage system 解题报告
    • GCD Determinant 解题报告
    • Southeastern European 2008 Sky Code 解题报告
    • HDU HDOJ 3400 Line belt 解题报告
    • 线性筛法求质数(素数)表 及其原理
    • HDU HDOJ 3398 String 解题报告
    • 树状数组模块(个人模板)
    • 浙江理工 省赛总结 team62 By OWenT of Coeus
    • POJ PKU 3659 Cell Phone Network 解题报告
    • USACO 2008 March Gold Cow Jogging 解题报告
    • C#格式化输出(记录)
    • 参加有道难题笔记
    • POJ PKU 2446 Chessboard 解题报告
    • POJ PKU 1986 Distance Queries 解题报告
    • 计算几何算法概览[转载]
    • 关于差分约束(转载)
    • POJ PKU 2826 An Easy Problem?! 解题报告
    • 数论模板(个人模板)
    • 简易四则运算(ACM个人模板)
    • Catalan 数
    • The 35th ACM/ICPC Asia Regional Tianjin Site —— Online Contest 1009 Convex 解题报告
    • JQuery扩展插件--提示信息
    • ACM 计算几何 个人模板
    • 解析网站字符串型参数 Javascript QueryString 操作 TQueryString类
    • POJ PKU 1474 Video Surveillance 解题报告
  • 2009
    • 模式匹配(kmp)个人模板
    • 并查集 模板
    • POJ 3267 The Cow Lexicon 解题报告
    • C/C++语言常用排序算法
    • POJ 2606 Rabbit hunt 2780 Linearity 1118 Lining Up 解题报告
    • 打造最快的Hash表(转) [以暴雪的游戏的Hash为例]
    • ECUST 09年 校赛个人赛第六,七场总结
    • ECUST 09年 校赛个人赛第三场部分解题报告(A,D,F,I)
    • 牛顿迭代解方程 ax^3+bX^2+cx+d=0
    • 09年8月9日 ECUST ACM 练习赛总结
    • 连接最多点直线 (OWenT 个人模板)
    • 点到直线距离 和 线段间最短距离 (OWenT 模板)
    • ECUST 09年 校赛个人训练赛第五场总结
    • ECUST 09年 校赛个人赛第八场(最后一场)总结
    • 09年8月14日 ECUST ACM 练习赛总结
    • 矩阵相关 (增强中)
    • Prime最小生成树(个人模板)
    • 最长单调子序列 复杂度nlog(n)
    • POJ PKU 2549 Sumsets 解题报告
    • POJ PKU 3277 City Horizon 解题报告
    • 我的ACM生涯
    • POJ PKU 2528 Mayor's posters 解题报告
    • POJ PKU 2378 Tree Cutting 解题报告
    • POJ PKU 1990 MooFest 解题报告
Powered by GitBook
On this page

Was this helpful?

  1. 2011

2011 Google Code Jam 小记

Previous非常帅气的Linq to sqlNextC++总是很神奇

Last updated 6 years ago

Was this helpful?

好久没写这种类型的代码,感觉真是退步了很多。 这是我第一次参加Google Code Jam,以前有过报名可是没有做过。 我发现Google Code Jam的题目使用经典算法的几乎没有,都是模拟或者数学题(起码我目前做过的几题是这样)

首先是Qualification Round 四道水题,前两道模拟,后两道数学推公式。 第三道是位运算的,第四道由于那天没空了就没做,反正分数够了,听人说也是推公式的水题。 题目链接:

// 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;
}
// Qualification Round -- B
#include <iostream>
#include <cstdio>
#include <map>
#include <string>
#include <set>
#include <cmath>

namespace gcj {
    using namespace std;
    string ls;
    map<char, char> combine[256];
    map<char, char>::iterator comItr;
    set<char> opposed[256];
    //set<char>::iterator oppItr;
    //int charNumber[256];

    void init() {
        ls.clear();
        for (int  i = 0; i < 256; i ++) {
            combine[i].clear();
            opposed[i].clear();
        }
        //memset(charNumber, 0, sizeof(charNumber));
    }

    void solve() {
        int t, c, d, n;
        char comStr[5], oppStr[5];
        char input[105];
        scanf(" %d", &t);
        for (int i = 0; i < t; i ++) {
            init();

            scanf(" %d", &c);
            for(int j = 0; j < c; j ++) {
                scanf(" %s", comStr);
                combine[comStr[0]][comStr[1]] = combine[comStr[1]][comStr[0]] = comStr[2];
            }

            scanf(" %d", &d);
            for(int j = 0; j < d; j ++) {
                scanf(" %s", oppStr);
                opposed[oppStr[0]].insert(oppStr[1]);
                opposed[oppStr[1]].insert(oppStr[0]);
            }

            scanf(" %d", &n);
            scanf(" %s", input);
            for(int j = 0; j < n; j ++) {
                char key = input[j];
                bool run = true;
                //oppItr = opposed[key].begin();

                if (ls.size() > 0) {
                    if ((comItr = combine[key].find(ls.back())) != combine[key].end()) {
                        //charNumber[ls.back()] --;
                        ls.pop_back();
                        ls.push_back(comItr->second);
                        //charNumber[comItr->second] ++;
                        run = false;
                    }

                    if (run) {
                        for (int k = 0; k < ls.size(); k ++) {
                            if (opposed[key].find(ls[k]) != opposed[key].end()) {
                                //ls = ls.substr(0, k);
                                ls.clear();
                                run = false;
                            }
                        }
                    }
                    //while (run && oppItr != opposed[key].end()) {
                    //    if (charNumber[*oppItr] > 0) {
                    //        while(ls.back() != *oppItr) {
                    //            charNumber[ls.back()] --;
                    //            ls.pop_back();
                    //        }
                    //        charNumber[ls.back()] --;
                    //        ls.pop_back();
                    //        run = false;
                    //    }
                    //    oppItr ++;
                    //}
                }

                if (run) {
                    ls.push_back(key);
                    //charNumber[key] ++;
                }
            }

            printf("Case #%d: [", i + 1);
            for (int j = 0; j < ls.size(); j ++) {
                if (j > 0) {
                    putchar(',');
                    putchar(' ');
                }
                putchar(ls[j]);
            }
            puts("]");
        }

    }
}

int main () {

    //freopen("d:/GCJ/B-large.in", "r", stdin);
    //freopen("d:/GCJ/B-large.out", "w", stdout);

    gcj::solve();
    return 0;
}
// Qualification Round -- C
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

namespace gcj {
    using namespace std;

    void solve() {
        int t, n, min_val, sum_val, number, sum_xor;

        scanf("%d", &t);
        for (int i = 0; i < t; i ++) {
            min_val = 1<< 20;
            sum_val = sum_xor = 0;
            scanf(" %d", &n);
            for (int j = 0; j < n; j ++) {
                scanf(" %d", &number);
                sum_xor ^= number;
                sum_val += number;
                min_val = min(min_val, number);
            }

            if (sum_xor)
                printf("Case #%d: NO\n", i + 1);
            else
                printf("Case #%d: %d\n", i + 1, sum_val - min_val);
        }

    }
}

int main () {

    //freopen("d:/GCJ/C-large.in", "r", stdin);
    //freopen("d:/GCJ/C-large.out", "w", stdout);

    gcj::solve();
    return 0;
}
#include <cstdio>
#include <algorithm>

namespace gcj {
    void print(int t, char* str) {
        printf("Case #%d: %s\n", t, str);
    }

    int gcd(int a, int b) {
        return b ? gcd(b, a % b) : a;
    }

    void solve() {
        int t, n, pd, pg, d, g, l, r;
        scanf("%d", &t);
        for (int i = 0; i < t; i++) {
            scanf("%d %d %d", &n, &pd, &pg);
            d = gcd(pd, 100);
            if ((pd < 100 && pg == 100)
                || (pd > 0 && pg == 0)
                || n < 100 / d)
                print(i + 1, "Broken");
            else
                print(i + 1, "Possible");
        }
    }
}

int main () {

    freopen("d:/GCJ/Round1/A-small-practice.in", "r", stdin);
    freopen("d:/GCJ/Round1/A-small-practice.out", "w", stdout);

    gcj::solve();
    return 0;
}

第二题是猜字游戏 看了大牛的代码,用了DFS,两次精妙的索引排序解决了。太强大了,我还有差距呵。

#include <cstdio>
#include <cstring>

namespace gcj {
    using namespace std;

    const int maxn = 105;
    char mat[maxn][maxn];
    double WP[maxn];
    double WP_par[maxn][2];
    double OWP[maxn];
    double OOWP[maxn];

    void solve() {
        int t, n, c = 0;
        scanf("%d", &t);
        while (t --) {
            c ++;
            scanf("%d", &n);
            for (int i = 0; i < n; i ++)
                scanf("%s", mat[i]);

            // WP
            for (int i = 0; i < n; i ++) {
                double sum = 0.0, win = 0.0;
                WP_par[i][0] = WP_par[i][1] = 0.0;
                for (int j = 0; j < n; j ++) {
                    if (mat[i][j] == '.')
                        continue;
                    sum += 1.0;
                    if (mat[i][j] == '1')
                        win += 1.0;
                }
                WP_par[i][0] = win;
                WP_par[i][1] = sum;
                WP[i] = win / sum;
            }

            // OWP
            for (int i = 0; i < n; i ++) {
                double sum = 0.0, win = 0.0;
                for (int j = 0; j < n; j ++) {
                    if (mat[i][j] == '.')
                        continue;
                    sum += 1.0;
                    if (mat[i][j] == '1')
                        win += (WP_par[j][0]) / (WP_par[j][1] - 1.0);
                    else
                        win += (WP_par[j][0] - 1.0) / (WP_par[j][1] - 1.0);
                }
                OWP[i] = win / sum;
            }

            // OOWP
            for (int i = 0; i < n; i ++) {
                double sum = 0.0, win = 0.0;
                for (int j = 0; j < n; j ++) {
                    if (mat[i][j] == '.')
                        continue;
                    sum += 1.0;
                    win += OWP[j];
                }
                OOWP[i] = win / sum;
            }

            // Output
            printf("Case #%d:\n", c);
            for (int i = 0; i < n; i ++) {
                printf("%.12lg\n", 0.25 * WP[i] + 0.50 * OWP[i] + 0.25 * OOWP[i]);
            }
        }
    }

}

int main() {
    freopen("A-large.in", "r", stdin);
    freopen("A-large.out", "w", stdout);
    gcj::solve();
    return 0;
}

第二题是一个数学题,又是数学题,问最少多久能让任意两个热狗店距离不小于d,计算的时候只要考虑往一个方向走,然后最后答案除以2即可,因为运动是对称的。中途需要考虑的是两个相邻组的距离问题,然后对分散时间进行合并取大值,并考虑交叉的情况加上分开交叉情况的时间即可。又是64位整形,不过这次我注意到了。不过那个maxn貌似我忘记改成大数据的数字了,为什么过了,神奇的。

#include <cstdio>
#include <cstring>
#include <algorithm>

namespace gcj {
    using namespace std;

    const int maxn = 206;
    typedef long long lld;

    struct node{
        lld p;
        lld v;
    };
    bool cmp(const node& l, const node& r) {
        return l.p < r.p;
    }

    node venders[maxn];

    void solve() {
        int t, n, _case = 0;
        scanf("%d", &t);
        while (t --) {
            _case ++;
            int d, c;
            scanf("%d %d", &c, &d);
            for (int i = 0; i < c; i ++)
                scanf("%lld %lld", &venders[i].p, &venders[i].v);

            sort(venders, venders + c, cmp);
            lld tmp, tl, last;
            lld sum = (venders[0].v - 1) * d;
            for (int i = 1; i < c; i ++) {
                tmp = (venders[i].v - 1) * d;
                tl = venders[i].p - venders[i].v * d;
                if (tmp > sum) {
                    last = venders[i - 1].p - (tmp - sum);
                    if(tl >= last)
                        sum = tmp;
                    else
                        sum = tmp + last - tl;
                } else {
                    last = venders[i - 1].p;
                    if (tl >= last) {
                        lld _m = min(tl - last, sum - tmp);
                        venders[i].p -= _m;
                    } else {
                        sum += last - tl;
                    }
                }
            }

            printf("Case #%d: %.1lf\n", _case, sum / 2.0);
        }
    }

}

int main() {
    freopen("D:/GCJ/Round2/B-large.in", "r", stdin);
    freopen("D:/GCJ/Round2/B-large.out", "w", stdout);

    gcj::solve();
    return 0;
}

Round2期间正碰上期末考试,但是我还是来做了一下,很失望的没拿到衣服。感觉我的编码能力还差得远呐,因为AC两题应该就能拿到衣服了,可是遗憾在第二题。 A很简单,大意是一个人在一条路上走,可以跑t秒,告诉走路和跑步的速度,再有的是路上有n个不重叠的walkway,在walkway上的速度等于walkway的速度+当前速度,问最少几秒钟到终点。思路非常简单,就是要在walkway上加速尽量多的时间。有两种情况,一种是在没有walkway的路上跑步跑完了t秒,这种情况时间很好算。另一种是walkway之外的路上t秒没用完,这时后要尽量在速度快的walkway上加速,所以对walkway的速度排序就可以了。需要注意的情况就是从头跑到尾的情况。 A题代码:

#include <cstdio>
#include <algorithm>
#include <cstring>

namespace gcj{
    using namespace std;

    const int MAXN = 1005;
    struct walkway{
        int b, e, w;
        friend bool operator< (const walkway& l, const walkway& r) {
            return l.w < r.w;
        }
    };

    walkway cors[MAXN];

    void solve(int T) {
        int x, s, r, t, n;
        int wwlen = 0, rlen;
        double res = 0.0, rt;

        scanf("%d %d %d %d %d", &x, &s, &r, &t, &n);
        for (int  i = 0; i < n; i ++)
            scanf("%d %d %d", &cors[i].b, &cors[i].e, &cors[i].w), wwlen += cors[i].e - cors[i].b;
        rlen = x - wwlen;
        rt = t;
        sort(cors, cors + n);

        if(rlen >= t * r)
            res = 1.0 * (rlen - t * r) / s + t, rt = 0.0;
        else
            res = 1.0 * rlen / r, rt -= res;

        for (int  i = 0; i < n; i ++) {
            if (rt <= 0.0) {
                res += 1.0 * (cors[i].e - cors[i].b) / (s + cors[i].w);
                continue;
            }
            if (1.0 * (cors[i].e - cors[i].b) / (r + cors[i].w) <= rt) {
                res += 1.0 * (cors[i].e - cors[i].b) / (r + cors[i].w);
                rt -= 1.0 * (cors[i].e - cors[i].b) / (r + cors[i].w);
            } else {
                res += 1.0 * (cors[i].e - cors[i].b - (r + cors[i].w) * rt) / (s + cors[i].w) + rt;
                rt = 0.0;
            }
        }

        printf("Case #%d: %.9lf\n", T + 1, res);
    }

    void solve() {
        int t;
        scanf("%d", &t);
        for (int i = 0; i < t; i ++)
            solve(i);
    }
}

int main() {
    freopen("E:/OWenT/GCJ/R2/A-large.in", "r", stdin);
    freopen("E:/OWenT/GCJ/R2/A-large.out", "w", stdout);

    gcj::solve();
    return 0;
}

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题代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

namespace gcj {
    using namespace std;

    const int maxn = 505;
    typedef long long lld;

    char inputStr[maxn];
    struct grid{
        lld r, c, w;
        grid(): r(0), c(0), w(0){}
        grid(lld a, lld b, lld c): r(a), c(b), w(c){}

        friend grid operator+(const grid& l, const grid& r) {
            return grid(l.r + r.r, l.c + r.c, l.w + r.w);
        }

        friend grid operator-(const grid& l, const grid& r) {
            return grid(l.r - r.r, l.c - r.c, l.w - r.w);
        }
    };

    grid grids[maxn][maxn];
    grid sum[maxn][maxn];

    void solve() {
        int t, r, c, d, res;
        scanf("%d", &t);

        for (int tc = 0; tc < t; tc ++) {
            scanf("%d %d %d", &r, &c, &d);
            res = 0;

            for (int i = 1; i <= r; i ++) {
                scanf(" %s", inputStr);
                for (int j = 1; j <= c; j ++) {
                    grids[i][j].w = d + inputStr[j - 1] - '0';
                    grids[i][j].r = i * grids[i][j].w;
                    grids[i][j].c = j * grids[i][j].w;

                    sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + grids[i][j];
                }
            }

            for (int i = 1; i <= r; i ++) {
                for (int j = 1; j <= c; j ++) {
                    for (int k = max(3, res + 1); k + i - 1 <=r && k + j - 1 <= c; k ++) {
                        int ti = k + i - 1, tj = k + j - 1;
                        //if ((i + ti) % 2 || (j + tj) % 2)
                        //    continue;
                        grid gd = sum[i - 1][j - 1] + sum[ti][tj] - sum[i - 1][tj] - sum[ti][j - 1]
                            - grids[i][j] - grids[i][tj] - grids[ti][j] - grids[ti][tj];
                            if (((i + ti) % 2 + 1) * gd.r % gd.w != 0 || ((j + tj) % 2 + 1) * gd.c % gd.w != 0)
                                continue;
                            if (2 * gd.r / gd.w != i + ti || 2 * gd.c / gd.w != j + tj )
                                continue;
                            res = max(res, k);
                    }
                }
            }

            if(res)
                printf("Case #%d: %d\n", tc + 1, res);
            else
                printf("Case #%d: IMPOSSIBLE\n", tc + 1);
        }
    }
}

int main() {
    freopen("D:/GCJ/R2/B-large-practice.in", "r", stdin);
    freopen("D:/GCJ/R2/B-large-practice.out", "w", stdout);

    gcj::solve();
}

唉,真心还需要学习提高水平啊。

然后是Round 1A 2011 状态不好,能力有限,我只看了第一和第二题 题目链接: 第一题是告诉你一个今天最大比赛数量、今天胜率、总胜率,问数据是否可能达到. 我的想法是正确的,只有在计算符合今日胜率的最小局数和考虑总胜率为100和为0的情况即可,其他经过我简单的证明都是可行的,但是在获取最小的满足“今天胜率”的今日比赛数量的时候少打了一组括号,并且每注意到大数据范围到10^15,直接导致小数据PASS,大数据挂掉. 后来看了大牛的代码发现他用了最大公约数来解这个值,非常好。 贴小数据代码,大数据只要换到64位整数即可

然后是Round 1B 2011 题目链接: 这个发挥得比较好,拿到了晋级名额。 我也只写了两道题,但是方法都对,而且都是1A,最后一道题我发现只剩下25分钟了,而且很晚了,反正写不完就懒得写了 第一题是模拟,按题目说的做就好了,这题在大数据的时候freopen的路径写错了,结果我一直在想为什么会TLE,还好在提交限时的两分钟前看到了,马上改掉就ok了。

http://code.google.com/codejam/contest/dashboard?c=975485
http://code.google.com/codejam/contest/dashboard?c=1145485
http://code.google.com/codejam/contest/dashboard?c=1150485