Codeforces科学刷题指南,一图一表便够了

2023-05-16

简要介绍如何科学地刷算法题,来提高自己解决问题的能力,并利用爬虫抓取Codeforces的题库,来分析题目难度以及算法分类的关系

无论做什么事,多尝试、找套路、然后刻意练习都是至关重要的。对信息科学竞赛(Olympiad in Informatics)爱好者来说,找套路的关键就是多刷题。然而题海茫茫,单以Codeforces来说,截止2017年1月3日,总共有3206道题。换言之,如果一个人足够勤奋,能够一天刷三道题,那也得快三年才能把题目刷完,而且题目数量还在扩充。所以盲目的刷题简直是浪费生命,本人从16年上半年一直按照题目解决人数从高到低排序,不断的刷水题。显然易见,刷水题的后果就是没有长进,熟悉的还是熟悉,不懂的还是不懂,唯一让自己开心的就是刷题数量的累积。所以科学刷题的本质在于不断挑战新高度,在一个平台练习足够久足够熟练之后,就要进入下一个难度平台。为了方便大家,我把Codeforces上截止2017年1月3日的所有题目的基本信息用爬虫收集了下来,并存储到excel里。更进一步,本文试图分析不同算法在不同难度等级上的出现频率分布,以及不同算法在不同难度等级上被解决次数的分布。最后,我会简要介绍的我的刷题观,以及如何爬取Codeforces上的信息。

先说结论

一张图

Codeforces_Algorithms_Tag_Frequency.jpgCodeforces_Algorithms_Tag_Frequency.jpg

上面这张图反映了不同算法(第一列)在不同问题难度(第一行)上的频率分布,基于该图,大概就可以知道在什么样的水平下应该掌握什么样的算法。不过这里我没有区分Div1和Div2之间的差别,仅仅是按照题号(A、B、C等等)来推断难度。可以看到对简单的A题而言,大部分都是考察基本的编程功底,诸如implementation(大概就是题目说什么,你做什么就是了),math(四则运算、取模取整等等)以及brute force(暴力枚举)。而随着难度的增加,比如说E题,主要就在于考察对dp(动态规划),data structures(数据结构)。当然了,从图中也可以看出,高难度题目主要在math,geometry(计算几何),shortest path(图论)以及games(博弈)上。下面再免费附送领一张图,反映了不同算法在不同问题难度上被解决次数的频率分布。

Codeforces_Algorithms_Tag_Solved.jpgCodeforces_Algorithms_Tag_Solved.jpg

一张表

Codeforces-ProblemSet.jpgCodeforces-ProblemSet.jpg

然后祭上刷题目录,也就是这一张表,汇总了截止2017年1月3日Codeforces题目上的所有算法题。基于这张表,一来可以按照解决人数来进行刷题,二来可以按照题目难度进行刷题,三来还可以进行主题刷题。具体的文件下载链接请见文末。

我的刷题观

这里搬来我在知乎上的回答,详见 LeetCode按照怎样的顺序来刷题比较好?

  • 如果想提升自己的思维能力 ,可以按照AC率或者解决人数由低到高二分查找匹配自己当前水平难度的题目,然后适当挑战高难度题(二分时间复杂度是  O(logN) O(log⁡N) ,至少比从易到难的  O(N) O(N) 节省时间)
  • 如果想巩固某一专题 ,那自然应该按照tag来刷题,但是因为所用的方法在求解前已知,不太利于思维能力的提升
  • 如果什么都不懂 ,那么建议随机刷题,一来可以涨见识,二来进步空间比较大
  • 如果想提高AC率或者增加自信 ,那么建议刷水题
  • 混搭以上策略 ,比如针对某一专题,然后用二分查找来选择问题求解

再有个建议,题目如果太难超过自己当前能力的话,尝试一定时间后还是老老实实看题解吧,人与人之间还是有天赋差别的,但区别在于经验可以慢慢积累。特别是即使做对题之后,还要想尽办法看有没有提高的余地,并参考别人的代码,看如何精简代码以及精简时间空间复杂度。

tourist.jpgtourist.jpg

据说大神们的刷题量都是上万的,所以正式比赛里可以看到诸多大神不到一分钟就秒了一道题,手速太快。对Competitive Programming而言,把题目做对是基本要求(题目太难则另当别论),用更快的速度求解才是顶尖高手之间的核心区别。如果说真的有天赋存在的话,那我们也无能为力;但希望能像卖油翁一样说出,『无他,但手熟尔』。

如何用爬虫获取信息

必要的库


1: import re
2: import urllib.request
3: from bs4 import BeautifulSoup
4: import os
5: import csv
6: import time

爬取Codeforces的所有算法题


 1: #%% retrieve the problem set
2: def spider(url):
3: response = urllib.request.urlopen(url)
4: soup = BeautifulSoup(response.read())
5: pattern = {'name': 'tr'}
6: content = soup.findAll(**pattern)
7: for row in content:
8: item = row.findAll('td')
9: try:
10: # get the problem id
11: id = item[0].find('a').string.strip()
12: col2 = item[1].findAll('a')
13: # get the problem title
14: title = col2[0].string.strip()
15: # get the problem tags
16: tags = [foo.string.strip() for foo in col2[1:]]
17: # get the number of AC submissions
18: solved = re.findall('x(\d+)', str(item[3].find('a')))[0]
19: # update the problem info
20: codeforces[id] = {'title':title, 'tags':tags, 'solved':solved, 'accepted':0,}
21: except:
22: continue
23: return soup
24:
25: codeforces = {}
26: wait = 15 # wait time to avoid the blocking of spider
27: last_page = 33 # the total page number of problem set page
28: url = ['http://codeforces.com/problemset/page/%d' % page for page in range(1,last_page+1)]
29: for foo in url:
30: print('Processing URL %s' % foo)
31: spider(foo)
32: print('Wait %f seconds' % wait)
33: time.sleep(wait)

标记已解决的算法题


 1: #%% mark the accepted problems
2: def accepted(url):
3: response = urllib.request.urlopen(url)
4: soup = BeautifulSoup(response.read())
5: pattern = {'name':'table', 'class':'status-frame-datatable'}
6: table = soup.findAll(**pattern)[0]
7: pattern = {'name': 'tr'}
8: content = table.findAll(**pattern)
9: for row in content:
10: try:
11: item = row.findAll('td')
12: # check whether this problem is solved
13: if 'Accepted' in str(row):
14: id = item[3].find('a').string.split('-')[0].strip()
15: codeforces[id]['accepted'] = 1
16: except:
17: continue
18: return soup
19:
20: wait = 15 # wait time to avoid the blocking of spider
21: last_page = 10 # the total page number of user submission
22: handle = 'Greenwicher' # please input your handle
23: url = ['http://codeforces.com/submissions/%s/page/%d' % (handle, page) for page in range(1, last_page+1)]
24: for foo in url:
25: print('Processing URL %s' % foo)
26: accepted(foo)
27: print('Wait %f seconds' % wait)
28: time.sleep(wait)

输出爬取信息到csv文本


 1: #%% output the problem set to csv files
2: root = os.getcwd()
3: with open(os.path.join(root,"CodeForces-ProblemSet.csv"),"w", encoding="utf-8") as f_out:
4: f_csv = csv.writer(f_out)
5: f_csv.writerow(['ID', 'Title', 'Tags', 'Solved', 'Accepted'])
6: for id in codeforces:
7: title = codeforces[id]['title']
8: tags = ', '.join(codeforces[id]['tags'])
9: solved = codeforces[id]['solved']
10: accepted = codeforces[id]['accepted']
11: f_csv.writerow([id, title, tags, solved, accepted])
12: f_out.close()

分析题目难度以及算法分类的关系


 1: #%% analyze the problem set
2: # initialize the difficult and tag list
3: difficult_level = {}
4: tags_level = {}
5: for id in codeforces:
6: difficult = re.findall('([A-Z])', id)[0]
7: tags = codeforces[id]['tags']
8: difficult_level[difficult] = difficult_level.get(difficult, 0) + 1
9: for tag in tags:
10: tags_level[tag] = tags_level.get(tag, 0) + 1
11: import operator
12: tag_level = sorted(tags_level.items(), key=operator.itemgetter(1))[::-1]
13: tag_list = [foo[0] for foo in tag_level]
14: difficult_level = sorted(difficult_level.items(), key=operator.itemgetter(0))
15: difficult_list = [foo[0] for foo in difficult_level]
16:
17: # initialize the 2D relationships matrix
18: # matrix_solved: the number of AC submission for each tag in each difficult level
19: # matrix_freq: the number of tag frequency for each diffiicult level
20: matrix_solved, matrix_freq = [[[0] * len(difficult_list) for _ in range(len(tag_list))] for _ in range(2)]
21:
22:
23: # construct the 2D relationships matrix
24: for id in codeforces:
25: difficult = re.findall('([A-Z])', id)[0]
26: difficult_id = difficult_list.index(difficult)
27: tags = codeforces[id]['tags']
28: solved = codeforces[id]['solved']
29: for tag in tags:
30: tag_id = tag_list.index(tag)
31: matrix_solved[tag_id][difficult_id] += int(solved)
32: matrix_freq[tag_id][difficult_id] += 1

下载本文源代码以及分析结果

本文源代码以及分析结果请见 我的Github ,或者点击链接下载: https://pan.baidu.com/s/1o7P8oT8 密码: 8dcb。








本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Codeforces科学刷题指南,一图一表便够了 的相关文章

  • [模板] 线性筛素数 (欧拉筛)

    模板 素数筛 P3383 模板 线性筛素数 洛谷 计算机科学教育新生态 题目背景 本题已更新 xff0c 从判断素数改为了查询第 k 小的素数 提示 xff1a 如果你使用 cin 来读入 xff0c 建议使用 std ios sync w
  • WSL+Systemd+Gnome+VcXsrv+CUDAToolkit 安装

    我的版本信息 wsl xff1a PS C Users kirk gt wsl update 正在检查更新 无更新使用 内核版本 xff1a 5 10 102 1 Ubuntu xff1a kirk 64 KirkComputer lsb
  • java上位机

    可以做 xff0c 我有做好的底层通讯程序 xff0c 无需了解通讯协议 xff0c 只要正确配置就可以读出相应的寄存器的值 xff0c 数据类型支持short xff0c int xff0c float等 xff0c 我也有做好的界面 x
  • java上位机的界面

  • Lanelet2高精地图3——LineString(线串)介绍

    LineString线串是两个或者多个点生成的有序数组 xff0c 用来描述地图元素的形状 线串可以通过高度离散化实现 xff0c 来描述任何一维形式 xff0c 并应用于地图上的任何可物理观察到的部分 与样条曲线相比 xff0c 线串可以
  • 香橙派的使用入门无屏幕安装系统

    首先我购买的是香橙派pipc这款开发板价格在105块 xff0c 需要购买散热片以及风扇 电源需要一个5v3安的电源 xff0c 系统有时候会运行不正常 一开始没有屏幕就需要一根usb转ttl的串口线 xff0c 注意不是usb转232 软
  • 香橙派进入系统后设置ip

    Debian 可以配置静态IP 动态IP使Debian连上互联网 用户使用nano编辑器编辑interface网卡配置文件 xff0c 为Debian系统指定本网络中的唯一IP地址 xff0c 使其能上网 方法 步骤 将用户当前目录切换到网
  • 香橙派更改中文界面以及安装输入法

    第一步更新语言包 sudo apt get install locales 第二部选择 sudo dpkg reconfigure locales 找到语言包空格键选中变 最后安装 scim 输入法相关 xff1a apt get inst
  • 香橙派添加启动脚本

    sudo nano etc rc local 后台启动 nohup root frp frpc c root frp frpc ini amp 查询日志 cat nohup out java jar root aaa jar
  • app远程访问plc实现方法

    工业上越来越多的人需要将局域网内的plc数据或者单片机的数据上传到手机app上 xff0c 实现远程的操作监控 实现的方法是借助plc支持modbus协议 xff0c 通过dtu模块实现串口透传到云服务器 xff0c 之后开发手机app实现
  • java访问西门子300plc以及仿真的测试方法

    安装step7软件 支持win7 64位系统 安装仿真软件plc sim 之后以管理员身份运行Nettoplcsim 下bin下的NetToPLCsim
  • Shell 批量拉取docker镜像(当前目录和指定目录)

    批量拉取docker容器镜像 拉取当前文件夹内的容器镜像 xff1a span class token shebang important bin sh span span class token comment 当前路径 span spa
  • docker-compose部署Jenkins+Gitlab CICD

    docker compose 搭建CICD jenkins 43 gitlab 1 修改yum源 xff08 1 xff09 备份原来的yum源 mv etc yum repos d CentOS Base repo etc yum rep
  • kubernetes Pod高级用法-探针

    POD 2高级用法 容器探测详解 所谓容器探测就是我们在里面设置了一些探针 xff0c 或者传感器来获取相应的数据用来判断容器存活与否或者就绪与否的标准 xff1b 目前k8s支持的存活性探测方式和就绪性探测方式都是一样的 xff0c 探针
  • 云原生工程师-1.容器相关

    个人博客地址 一 docker容器相关 1 服务器虚拟机容器的区别基础知识 k8s1 24之前 xff1a docker 1 24之后containerd docker主要制作镜像 xff1a docker build xff0c dock
  • nginx配置后转发没有生效的一个坑个人总结

    一 概述 nginx配置规则还是有点复杂的 xff0c 在此只总结下本人遇到的一个坑与解决方法 xff0c 具体原因还不清楚 二 配置后没有生效的坑 1 首先 xff0c 要访问的url样例是 xff1a http 10 123 123 1
  • 云原生工程师-6.k8s四层负载均衡-Service

    五 k8s四层负载均衡 Service 个人博客 5 1 什么是Service 5 1 1 Service作用 在 kubernetes 中 xff0c Pod 是有生命周期的 xff0c 如果 Pod 重启它的 IP 很有可能会发生变化
  • 云原生工程师-8.statefulset和daemonset

    七 Statefulset 有状态服务 个人博客 7 1 Statefulset相关概念 7 1 1 什么是Statefulset StatefulSet 是有状态的集合 xff0c 管理有状态的服务 xff0c 它所管理的 Pod 的名称
  • 云原生工程师-9.configmap和secret

    九 configmap 配置管理 个人博客 9 1 配置管理中心基本概念 9 1 1 什么是configmap Configmap 是 k8s 中的资源对象 xff0c 用于保存非机密性的配置的 xff0c 数据可以用 key value
  • 云原生工程师-10.K8s安全管理RBAC

    十一 K8s安全管理 xff1a 认证 xff0c 授权 xff0c 准入控制 个人博客 11 1RBAC概述 11 1 1安全管理概述 k8s 对我们整个系统的认证 xff0c 授权 xff0c 访问控制做了精密的设置 xff1b 对于

随机推荐

  • windows 10/11 wsl 安装 ubuntu

    微软官方连接 xff1a WSL 的手动安装步骤 Microsoft Learn 步骤 1 启用适用于 Linux 的 Windows 子系统 需要先启用 适用于 Linux 的 Windows 子系统 可选功能 xff0c 然后才能在 W
  • wsl2 与windows网络互通

    ubuntu wsl2 访问windows 方式一 xff1a ubuntu中查看 ubuntu终端中输入 cat etc resolv conf 显示结果 显示结果 This file was automatically generate
  • requires Python ‘>=3.7‘ but the running Python is 3.6.9 问题

    过程 ubuntu18 04 使用如下命令安装protobuf pip3 install protobuf 安装完毕后报错 protobuf requires Python 39 gt 61 3 7 39 but the running P
  • 拯救者Y9000P突然很卡

    描述 不知道什么原因 xff0c 拯救者Y9000P突然很卡 xff0c 打开windows 任务管理器 查看CPU性能显示速度不到1GHz 解决办法 关机 拔掉所有外设 xff0c 如鼠标 外接键盘 扩展屏幕 和其他设备 xff08 电源
  • windows电脑本通过网线分享无线网络

    条件 设备1 xff1a windows 10系统笔记本 xff08 wifi和网口 xff09 设备2 xff1a 具有网口的计算机 xff08 假设IP为 172 13 100 200 xff09 网线 期望 设备1通过wifi连接无线
  • shell中while内改变外部变量和 < << <<<

    代码 问题代码 使用管道会创建子shell lines 61 34 first line nsecond line nthird line 34 foo 61 0 echo e lines while read line do echo l
  • python 画几何图形

    多边形的画法 def ployon num distance bob color 39 blue 39 39 red 39 bob color 34 red 34 34 yellow 34 for i in range num bob fd
  • 希腊字母及读音

    希腊字母 24个希腊字母分别是 xff1a 拼写 xff1a 阿尔法 Alpha xff1a 贝塔 Beta xff1a 伽玛 Gamma xff1a 德尔塔 Delte xff1a 艾普西龙 Epsilon xff1a 捷塔 Zeta x
  • HexView工具使用

    HexView简介 HexView是Vector开发的一款查看和编辑16进制文件的PC端工具 它可以显示不同文件格式的内容 xff0c 主要是Intel HEX xff0c 摩托罗拉S记录二进制文件或其他汽车制造商特定的文件格式 此外 xf
  • c++ enum class转int

    示例 enum class 定义 span class token keyword enum span span class token keyword class span span class token class name Colo
  • cmake使用CMAKE_INSTALL_PREFIX指定目录的assimp

    编译assimp v5 2 5 CMakeLists txt片段 span class token comment 依赖库 span span class token function sudo span span class token
  • ubuntu14.04下eclipse4.5添加ADT插件构建android开发环境问题:libstdc++.so.6错误

    1 问题描述 xff1a ubuntu14 04 64位下 xff0c eclipse安装adt等android开发工具会提示 xff1a erro where loading shared libraries libstdc 43 43
  • 解决Win10下Linux子系统WSL输入who命令没有响应的内核问题

    系统和工具说明 Ubuntu 16 05 LTSWindows Terminalps xff1a powershellwsl xff1a windows子系统Linux 问题 在做操作系统的Linux的用户监测实验时 xff0c 我发现在W
  • vscode配置opencv环境【完整版】

    1 安装MinGW 并配置环境变量path 在终端输入gcc v验证 2 安装cmake 3 官方下载opencv源码source 在cmake中编译 xff0c 新建D opencv目录 先执行configure再执行generate o
  • 实验六:EIGRP协议配置

    EIGRP协议属于路由协议的一种 xff0c Cisco私有 xff0c 前身是IGRP xff0c 增加的 E 意为 增强型 xff0c 增强型内部网关路由协议 下面通过一个简单的小实验来学习一下EIGRP的相关命令 xff1a 拓扑图
  • Openstack容器部署工具—kolla-ansible源码解读

    kolla ansible源码解读 kolla介绍目录结构ansible目录结构 对neutron部署代码解读neutron目录结构defaulthandlersmetataskstemplates 命令参数解析 kolla介绍 Kolla
  • 离线升级:openssh从8.1版本至8.4版本

    由于公司有内外网之分 xff0c 因此内网的升级需要将所需要的包从外网传到内网进行离线升级 如果大家也是这种情况 xff0c 建议升级的时候务必要先拿一台不常用服务器 xff08 测试环境的话如果不常用也可以在上面升级 xff09 试一下
  • debian 10 修改网卡名称为eth0

    1 编辑文件 etc default grub 修改下面的值 初始值 GRUB CMDLINE LINUX 61 34 34 修改后 GRUB CMDLINE LINUX 61 34 net ifnames 61 0 biosdevname
  • ubuntu 安装过程中 安装界面卡死完美解决办法 笔记本

    在安装ubuntu过程中 xff0c 由于是神舟电脑 xff0c 问的淘宝客服 xff0c 没想到比我还白 xff0c 在网上搜了资料 xff0c 总结如下 xff1a 1 设置优盘启动 这里就不多说了 xff0c 网上资料很多 xff0c
  • Codeforces科学刷题指南,一图一表便够了

    简要介绍如何科学地刷算法题 xff0c 来提高自己解决问题的能力 xff0c 并利用爬虫抓取Codeforces的题库 xff0c 来分析题目难度以及算法分类的关系 无论做什么事 xff0c 多尝试 找套路 然后刻意练习都是至关重要的 对信