HDU 6657 – Acesrc and Cube Hypernet

题意: 给一个纸条,问是否可以折成一个立方体,纸条用一个h*w的矩阵上的#来描述,h<=100,w<=100,T<=30(数据组数)。 分析: 当时多校赛场上读完题就想到了可以枚举点然后BFS填充格子,只要有一个起点能满足不重复地填充给出图形上的所有#号点,且立方体被填满,就输出yes。由于h<=100,w<=100,所以最大的正方体的边长为100/4=25,因此我们枚举点25*25,check使用25*25*6的复杂度可以完成。 不过因为后来跟榜先搞别的题去了这题就先放一边,结果我们队后来因为开车那题自闭到最后. 这题的难点在于处理BFS时转向的问题。 我们可以先建立一个三维坐标,第一维是所属的面,第二维和第三维是这个坐标在这个面中的位置。如下图所示,中间的数字是面坐标的编号。 然后对于编号1的面,向周围4个面走的时候都是直接走即可,不需要进行坐标变换。 而对于需要进行坐标变换的情况,比如从0这个面一直向上走,走到4,需要将x和y坐标对调,然后逆时针转90°,再继续填充这个格子。 对于6个面,向4个方向走只有6*4=24种情况,所以直接把这24种情况x和y和方向的变化写出来(可以用if或者switch),然后直接做就完了。 然后就直接上一段很丑的代码吧。(为什么这么丑还要写博客呢,因为这算是在多校期间补的题中AC的人最少的一道题吧) 代码: #include <bits/stdc++.h> using namespace std; int…

二维ST表学习笔记

众所周知,ST表是一种离线解决RMQ(区间最值)问题的方法。 可以在O(n \log {n} ) 的时间内进行预处理,然后在O(1)时间内查询到结果。 复习一维 我们先来复习一下,一维st表的预处理和查询过程。 对于预处理,我们先定义一个名为st的二维数组,其中st[i][j]表示以i为起点,从起点开始(含起点)往后2^j个元素的最值。 满足i+2^j-1不越界 因为2^0 = 1 ,因此st[i][0]=a[i] 然后我们用2个for循环去打表就行了 接着是查询,这里我画了个图来解释。 其中橙色的线表示两个区间。 一维代码…

CQU选课小技巧

很多CQU的学生都遇到一个问题,选课的时候明明选完了,但是在提交上去的最后一步却遇到了Service Unavailable的情况,导致选课全部作废,需要重新选。 其实,借助Chrome浏览器和Fiddler可以很好地帮助我们解决这个问题。   问题根源:抢课系统在遇到提交失败的时候会丢失我们所选课的列表 解决方案:使用抓包工具,如果提交选课结果没有成功,就将提交上去出错的请求重放一遍   这里就不继续阐述诸如“看见加载不要继续点刷新”一类大家都知道的小技巧了   选课之前,你需要先安装好Chrome和Fiddler,Chrome建议安装SwitchyOmega插件,并按照这样设置。 点击上面菜单的黑色圆圈 然后点击选项 之后点击“新建情景模式” 然后按照下图设置代理协议HTTP,代理地址127.0.0.1,代理端口8888 (这个是Fiddler的默认配置) 之后应用选项。 然后打开fiddler,点击Tools,Options,按照这样设置 去掉Capture…

把树莓派作为Wi-Fi路由器(IPv6 passthrough、5GHz 11ac)

最近刚入手了Raspberry Pi 3B+. 打算当做一个高可玩性的路由器用。 毕竟这代硬件配备了千兆以太网(受限于USB总线带宽只能跑到250Mbps左右),和11ac Wi-Fi(受限于SDIO总线只能跑到110Mbps左右)。 参考资料:https://www.raspberrypi.org/documentation/configuration/wireless/access-point.md 我准备实现以下几个功能: Wi-Fi工作在11ac模式(如果你想使用11n模式,建议在hostapd配置部分参考这里),达到433Mbps的Link Speed Wi-Fi共享以太网口的网络,IPv4使用NAT模式 IPv6使用穿透模式(可适用于几乎所有学校和家庭的IPv6环境,甚至你的手机开启个人热点后通过USB连接在Pi上也可以用这种方式使后端设备得到IPv6地址) 接下来开始操作: 0x00. 切换到root用户 sudo su 0x01….

在macOS下编写C++程序

还是由于最近身边许多同学换到了macOS,他们多数曾经是OIer或者大学打算读计算机,跑来问我如何在macOS下编写C++程序,这里介绍一下我的方法。 (如果你已经熟悉在Linux或是WSL下写程序,那这篇真的没啥好看的) 首先,你需要安装编译器。 由于Xcode会自带一个clang LLVM编译器(与gcc不同,如果写了UB可能会和gcc编译的程序运行结果不同),你只需要去App Store安装Xcode并运行一次即可。 然后,你需要安装一个代码编辑器。 推荐2个代码编辑器: Sublime Text Visual Studio Code 然后,准备一个好用的终端环境 推荐参考这篇文章:https://blog.cyyself.name/2018/07/macos/ 你可以选择先处理一下bits/stdc++.h问题 参考这里:https://github.com/tekfyl/bits-stdc-.h-for-mac 执行以下shell代码:…

macOS终端调教历程

工欲善其事,必先利其器。 最近,我的许多朋友换了电脑,其中有不少换了Mac。他们也常常来问我macOS下如何编译程序,VS Code与VS区别等等。其中他们多数是准备在macOS上学习C++、Python等语言。 考虑到身边许多朋友需要这个,而我自己的电脑也需要整理一下,所以今天把电脑数据备份了下然后重装了系统,希望能把我自己配置macOS的历程分享给大家,为大家提供一些帮助。 在做如下操作前,请先到App Store安装好Xcode。 由于Xcode下载需要等待较长时间,在此之前,你可以先了解一下基本的Unix命令。如cd、ls、echo、cat等。 顺带了解一下nano编辑器的使用。 首先,一个好用的软件包管理器有助于环境的配置。 经常使用Linux发行版的朋友肯定对包管理器不陌生。可以用它来管理安装的软件包,并实现软件批量升级。同时还可以一行命令搞定软件安装。比如Debian、Ubuntu使用的apt,CentOS、Fedora使用的yum。 这里推荐一个Mac上的包管理器,Homebrew。 我们只要打开浏览器,将中间的命令一整行复制下来,到终端中粘贴,然后回车。 在安装过程中,你可能遇到需要输入密码的时候。需要提醒大家的是,这里输入密码是看不到输入密码的提示的,许多初学者的感觉是密码没有输进去。不过不要紧,只要在键盘打完当前用户的密码,然后按回车即可。   第二,一个好用的Shell有助于效率的提升 在此安利一下zsh,一个比自带的bash好用得多的Shell,还有各种插件可以添加。 待homebrew安装完后,我们可以来安装一下zsh。 在终端中输入…

QQ坦白说解密教程 for iOS

最近QQ坦白说功能在我的好友之间十分火热,也因此催生了许多人想要查看坦白说发送者的欲望,考虑到网上没有太多的坦白说解密教程,这里打算自己写一个。 首先,你需要准备以下工具 一台iPhone 一台运行着Windows的电脑 在电脑上安装并运行fiddler抓包工具 iPhone和电脑在同一个Wi-Fi下,且可以内网互通(几乎所有的家庭网络都可以,但大部分学校等场所的Wi-Fi会进行客户端隔离,遇到这种情况可以请别人使用手机开热点) 在电脑上运行Fiddler,点击Tools菜单中的Options 进入HTTPS选项卡,左边按照如图设置,点击右边的Actions,然后点击Export Root Certificate to Desktop 再进入Connections选项卡,按照如图设置,特别是要去掉Act as system proxy on startup和勾上Allow…

我在OI中辗转的这千百天

 今天是2017年12月16日,距离NOIP2017结束已经过去一个多月了。我想写一篇文章来留念一下我在OI中辗转的这千百天。 0x01 初识OI 我最初知道NOI系列赛事是在初一的时候。 小学到初中有在跟着思明区青少年宫的老师学电脑机器人,当时在班上有个比我大岁的朋友,他刚上高中,知道了有NOIP这个比赛,后来他拉着我学Pascal入坑了。 那段时间他带我入门了Pascal,水平大概达到了会写校门外的树的程度,后来由于我的时间关系和他的时间关系没有继续往下学。当时由于周末还拿出一天上电脑机器人的课,所以也没有太多的闲暇时间。 后来到了NOIP报名的时候,我问了我们班主任能不能我们学校找个信息老师挂名去参加NOIP,之后便没有下文了。 其实现在想来,当时的水平甚至连通过普及组初赛都不够的。那个时候我的水平仅仅只是会用Pascal写入门难度的程序。并且那个时候的我也不了解算法和数据结构,对于计算机的学习处在一个以自己玩为住的状态。当时搞机器人,搞单片机。搞Web开发,搞C#、VB、易语言写点小程序。记得小学六年级的时候写了个控制飞机躲避障碍的游戏和弹球游戏就觉得自己很厉害了,现在自己看来这些东西真是小儿科。正如我当时写的弹球游戏需要考虑的圆以一定的速度和角度与直线碰撞的问题,我根本不会判,当时易语言有个组件叫画板,基于DirectPlay,判断物体碰撞只要设置速度和角度物体就会在屏幕上移动,碰撞的时候会调用一个事件,根本不需要像我写OI的计算几何题目一样去考虑各种东西,所以我当时根本没有想过要学习算法和数据结构,不明白它甚至可以帮忙升学,初中阶段也就把这个事情搁置了。 0x02 高一的NOIP2015 由于一直对计算机感兴趣。初中的时候希望中考能考上一个OI强校成为了一个目标。然而不幸的是,中考的时候考的很差,高中来到了厦门集美中学。 高中的第一节信息课,信息老师就在问我们全班同学有没有人知道NOIP这个比赛,我记得当时全班就我一个人举了手,然后和老师交换了联系方式,周日开始在学校上课。 当时我们学校OI班上大概有20个人,招人方式几乎只是问问谁感兴趣谁进来。其中还有个高二的学长和高二的学姐都是之前电脑制作拿过奖,就被我们老师拉去参加NOIP了。显然这和OI不是一个知识体系,毕竟我们也是老师带的第一届OIer。但不幸的是,初赛结束之后就只剩4个人参加提高组复赛了。而初中普及组的初赛通过人数还是挺多的。 后来自然就到NOIP2015了,然而当时什么算法都不会,只知道C语言的基本使用,也不会STL,甚至连搜索都不太熟练。最后Day 1T1做了出来,剩下的题目要么打个搜索,要么打个特解,要么打个输出random,最后得分150。当年恰逢CCF取消省三等奖,福建省计算机学会和省教育厅自己发省三等奖,当然这个奖自然是毫无卵用除了免信息会考。对我而言也是一个信心上的鼓励。 并且我也听说了福师大附中的hzwer,高一拿省三,高二省一,省选R2翻盘最后进队,最后NOI Ag…

用PuTTYgen在Windows下生成SSH密钥

如今,玩云计算的人越来越多,很多人都喜欢去租个云服务器做个博客或是挂一些需要长时间一直运行的程序。这些服务器也多数是Linux系统,但是服务器的问题是一个不可忽视的问题。常常能在日志中看到每天有大量IP尝试连接22端口,希望使用弱密码能够登录服务器。这些服务器被黑客攻下后往往会被用作DDOS肉鸡,造成重大的安全威胁。而实际上,用ssh密钥登录可以有效解决这一问题,至少在当下很难在有限的时间内根据rsa公钥破解出rsa私钥。 现在介绍Windows下用PuTTY gen工具生成SSH密钥的方法。 首先,打开PuTTY gen 点击Generate,然后在界面中晃动鼠标,PuTTY gen会根据鼠标移动的轨迹来生成一对rsa密钥 生成后结果如下图所示 之后,把这个Public Key复制下来,然后先登录到我们原来的服务器上。 由于OpenSSH Server默认读取用户主目录的.ssh/authorized_keys文件,所以我们把ssh的公钥放到该位置。 具体操作为,在用户主目录下建立.ssh文件夹,然后放置authorized_keys文件,在里面放上公钥 将刚刚复制的SSH公钥粘贴进去(PuTTY导出的密钥有时候会分行,请注意删除多余的换行符,authorized_keys里面可以放多个密钥,一行一个分开即可) 然后按Ctrl+X,按Y再按回车退出 之后,我们就可以使用刚刚生成的sshkey连接服务器了。 注意:SSH Pubkey是可以对外宣告的,但是Private Key一定要自己保存好。RSA采用非对称加密,具体原理参见我之前写的博文https://cyyself.name/2017/07/rsa-algorithm/,RSA身份认证原理一样,就是用客户端的Private…

将树形01背包优化到O(n*m)

有先决条件的背包问题通常是树形DP的一个典型问题。 常见的例题有选课(洛谷P2014、Vijos 1180) 这类问题的定义是,在背包中,我们需要先选某个物品,才能选择这个物品的子物品。最后求出在花费满足限制的情况下,实现最大的价值。 实际生活中的例子有选课、买家具等。 朴素的做法就是用邻接表将树存下来,然后用DFS去深度优先遍历这棵树。 DP方程如下 f[father][j] = max(f[father][j],f[father][j–k]+f[child][k–cost[child]]+weight[child]); 其中father为当前节点,child为这个节点的一个子节点。 不难看出这个需要两重循环,我们对于f[father][j]这个状态需要去枚举k一次次取max来求解最优问题。 相当于,我们需要枚举,对于这个物品我们需要使用它和它的子物品多少价值。 这样做出来的时间复杂度就是O(n*(m^2) ) 尽管大部分题目对于这样的时间复杂度是会放水的。   但是后来,有一次我想用树形DP去解决NOIP2006…

如何快速解关灯游戏-高斯消元

想必许多使用gnome桌面环境的用户都玩过一个自带游戏,那就是Lights Off,中文名叫关灯。 在这个游戏中,界面由2种状态的矩阵组成,用方格的亮与暗代表灯的开与关,当鼠标点击一个方块时,与它有公共边的方块和这个方块本身都会改变状态,由开变关或由关变开,相当于二进制中的异或运算。 那么,这个问题如何编程解决呢?我先从一年前的我什么算法都不会只会打搜索是如何解决这道题的。 首先,我们先确定一个规则,因为一个方块改变2次之后,等于没有进行任何一次改变,所以,我们可以肯定的是,一个方块最多改变一次。 所以,我们只要枚举每个方块被点击与没有被点击两种情况进行枚举,时间复杂度是O(2^(h*w)),h、w分别为矩阵的长宽。 显然,这个时间复杂度是不可接受的。我相信大多数人的智商,解决一个6*6的方格都比用这种方法等待计算机算快得多吧。 然后我们还可以用迭代加深搜索进行优化,从每次枚举1个方格,到每次枚举两个方格,再到每次枚举三个方格,这样的时间复杂度是O(玄学)。但一旦这个关卡所需的最少步数太多,也就无法在短时间内找到答案。 此外,我们可以使用广度优先搜索来取代迭代加深搜索,可以优化时间常数为迭代加深搜索的1/2,但有一个严重的后果,如果你的电脑没有足够的内存,根本无法存储如此多的状态数。我曾经写一个9*9的BFS就把我的16G内存给爆了。 那么,我们还有什么办法呢?剪枝?等待量子计算机帮助我们实现? 实际上,这是一个线性代数的问题。 我们可以采用高斯消元法来解这个异或方程。 对于每个方格的点击,有0和1两种情况,每个方格点击会对自己和周围的方格进行异或(xor)1计算。 那么,对于一个2*2的方格,我们期望从全0变成全1,可以列以下方程,对于方格中的格子,我们采用p(x,y)来表示。对于每个格子是否点击的状态,我们采用b(x,y)来表示。 其中,0为初始状态。 p(1,1)=1=0 xor b(1,1)…

使用ngrok架设你在NAT背后的服务器

如今,越来越多的家庭宽带取消了公网IPv4地址的分配,给许多人在外面连接自家网络服务带来了诸多不便,比如连接自己家电脑的RDP远程桌面或者获取自家NAS上的文件,为此,一个简单的解决方法就是使用ngrok作为外网端口映射。 本教程使用Debian 9为例。 首先,我们先去https://ngrok.com/注册一个账号。 之后便进入了ngrok的Dashboard页面,我们先点击Download把ngrok下载到自己的服务器(路由器/树莓派/….)上。 在这个下载页面上,我们用本机的浏览器访问,然后在相应的链接上获取链接地址。 对于树莓派/路由器等设备,选择Linux ARM,对于自己用PC组建的NAS等设备选择Linux 64-Bit。 然后我们ssh到自己的设备上,用wget命令下载相应版本的ngrok,并解压,安装到相应的目录,推荐/usr/bin (解压的时候需要unzip软件包,如果没有请使用apt install unzip来安装) 这里使用的shell命令包括: wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip unzip ngrok-stable-linux-amd64.zip…

关于clang和gcc你需要注意的问题

这两天写程序时遇到了许多clang和gcc规范的问题,明明自己Mac电脑上大样例都能过的程序交到OJ上一片WA和RE,百思不得其解怀疑是编译器问题,于是ssh到一台装了gcc的Linux机器上跑一下,果然结果和本地不一样。 函数传参的调用顺序 对于OIer而言,常见的一种优化程序常数的方法就是读入优化。用getchar手写输入,用putchar来取代手写输出。而许多人喜欢一种写法,就是写一个read函数,返回int类型,这样我们可以在调用函数的时候直接调用read,少写几行定义变量,然而,gcc和clang用这种方法时却存在差异。 在clang中,传递的参数默认从左边向右边调用,输入123 456,传给函数的便是a=123,b=456。而在gcc中,却有不同。这是gcc中运行同样代码的结果,可以看到,传递的参数从右边向左边调用。 位运算的异常 位运算也是一种优化程序和让程序更易读的方式,对于OIer而言,在状态压缩和二叉树节点编号中常用。 然而在clang中也有许多这样的坑。比如定义一个unsigned int a = 0xffffffff。 显而易见,它的二进制是全1。那么右移动32位,由于i>>k会被处理为i>>(k%sizeof(i)*8),所以相当于i>>0。 然而,gcc是这样,clang却不是。 而clang在处理位运算的时候似乎使用了一种不同于gcc的处理方式,所以我们还是手动%一下再操作吧。  

小绿锁背后的RSA算法

如今,我们上网时常能见到一把小绿锁,这便是多数浏览器对于HTTPS连接的标识。即HTTP over SSL,它代表着我们与网站服务器的连接是经过SSL加密的。然而,不论何种加密算法,总是有加密和解密的过程,其中最关键的就是密钥交换过程,如果在交换过程中这个密钥被窃取,之后的加密便毫无意义。那么SSL是如何确保即使我们的网络流量被抓取的情况下也能保证加密信息安全的呢?这就是我们今天要说的非对称加密算法,而最早的非对称加密算法便是从RSA开始。 算法介绍 RSA算法是1977年由麻省理工学院的Ron Rivest、Adi Shamir、Leonard Adleman三人共同提出的,RSA名字便取自他们三人的姓氏。在RSA算法之前,密钥交换主要采用预共享密钥的方式,例如我们生活中连接WPA2-PSK的Wi-Fi便是采用预共享密钥的方式,它的特点是需要通信双方事先共享密钥才能加密,也称为对称加密。而RSA采用的是非对称加密,需要生成两组密钥,称为公钥(Public Key)和私钥(Private Key),这两组密钥是成对的。使用公钥加密的数据可以被私钥解密,使用私钥加密的数据可以被公钥解密。 在了解这个算法前,你需要了解以下数学知识,我假设读者已经具备初中数学知识。 对于OIer,你如果了解过扩展欧几里得、欧拉函数、费马小定理,你可以跳过这一段,而且你看这个会很轻松。 最大公因数: Greatest Common Divisor,即两个数的因数集合的交集中最大的数,通常我们使用gcd表示。 例如a、b的最大公因数记为gcd(a,b) 互质关系:…

在移动硬盘上安装Windows To Go+Linux双系统(EFI)

自己多出了一块128G的SSD,本着闲着也浪费的想法就用了一个老的硬盘盒装起来当移动硬盘使用,没想到新固件还支持Trim,便有了在上面安装Windows To Go,然后给Mac提供Windows的想法。可是,安装完Windows的我似乎还不满足,还希望在上面安装一个Ubuntu系统,几经辗转,终于找到了办法。 话不多说,直接入题。 首先,备份移动硬盘上的数据,使用WTG辅助工具写入Windows系统文件,记得勾选UEFI+GPT。 用压缩卷空出一部分空间留给Linux使用 至此,我们已经完成了Windows的安装,并且这时直接启动移动硬盘已经可以使用Windows了。 将移动硬盘挂在到虚拟机中,记得使用EFI模式,比如VirtualBox勾上“启用EFI”,Hyper-V选择第二代虚拟机即可,在虚拟机中安装好所选的Linux发行版 待Linux安装完成后,此时的系统并不能直接启动的,若直接启动出现的是一个蓝屏的Windows,因为之前安装的grub没有使用removable模式,因此,我们手动安装grub 将/boot分区挂载到任意目录,这里我选择/target/boot,若没有单独分出/boot就直接挂载/到任意目录即可。同时,将ESP分区挂载到/target/boot/efi,然后删除EFI/Boot/bootx64.efi文件 安装grub-efi软件包 使用grub-install安装grub,之后便得到了一个可启动的Linux 来看看成果吧! 可以看出,grub已经接管了Windows Boot Manager,我们可以在这选择操作系统启动。 同样,在Mac上也没有问题 效果如图…

线段树入门

什么是线段树? 线段树,是一种二叉搜索树。它可以把一个从1…N的数组可以用二叉树划分为许多区间,这个区间成为二叉树的节点,使用线段树可以大大加快进行区间操作时的速度,同时,区间的最大值、最小值等问题也可以方便地使用线段树求出。 这里借用一下百度百科中的线段树图片来简要说明一下。 其中,[1,10]是我们的操作区间范围,这个节点作为根节点。 其下有两个子节点,一个是[1,5]一个是[6,10]。 对于每个节点[x,y],当x !=y 时其子节点分别为[x,(x+y)\2]与[(x+y)\2+1,y] 其中,\代表整除 当x == y时,没有子节点,即叶节点。 线段树能做什么? 看到这里,相信很多读者会问,在各个区间的节点上需要保存什么呢? 其实我相信聪明的读者已经看出来了,学过RMQ问题的读者应该已经想到了线段树是一个实现RMQ相比于ST算法占用内存空间更小的算法。实际上正是,例如POJ 2823,用st算法是过不了的。因此,我们还可以在线段树节点上存储区间的最大值、最小值、区间和、区间非0节点数量、区间0节点数量,等等等等。这样,对于一个区间的查询,只需要O(log n)的时间复杂度,相比于O(y-x),快了许多,因而,线段树非常适合解决区间操作的各类问题。 如何建树?…

POJ 2482 – Stars in Your Window 题目背景翻译

http://poj.org/problem?id=2482 飞逝的的时光不会模糊我对你的记忆。难以相信从我第一次见到你以来已经过去了4年。我仍然还生动地记得,4年前,在美丽的珠海校区,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的脸颊。我明白,我已经沉醉于你了。之后,经过几个月的观察和窥探,你的优雅与智慧,你对待生活的态度和你对未来的愿望深切地在我心中留下了印象。你是迷人的阳光女孩,我总是梦想着与你分享余生。唉,实际上你远远超过了我最疯狂的梦想。我不知道如何桥起我与你之间的鸿沟。所以我没有任何计划,仅仅只是等待,等待一个适当的机会到来。直到现在,毕业的到来,我意识到我是个傻瓜,我应该创造机会并且抓住它而不只是等待。 这些日子里,我和我的朋友、室友、同学一个接一个地分开。我仍无法相信,在挥手之后,这些熟悉的面孔很快就会从我们的生活中消失,仅仅留下回忆。我明天就将离开学校。你已经计划远走高飞,追求你的未来,实现你的梦想。如果没有命运,也许我们不会再次相遇。所以今晚,我正在你的宿舍楼下徘徊,希望能偶然遇见你。但矛盾的是,你的美貌一定会使我心跳加速,我笨拙的舌头也许无法吐出一个字。我不记得我曾多少次经过你在珠海和广州校区的宿舍楼,每次都希望看到你出现在阳台上或是窗台上。我不记得这个想法曾多少次在我的脑海中涌出:打电话叫她一起吃晚饭或是聊聊天。但每次,考虑到你的优秀和我的平凡,胆怯的优势超越勇气驱使我静静地离开。 毕业,意味着大学生活的终结。这些光荣与浪漫的时代结束。你可爱的微笑是我原来努力学习的动力,这单相思的爱情会被密封,作为一个我心灵深处的记忆。毕业,也意味着新生活的开始,一个到达光明未来的足迹。我真希望你在国外天天开心,一切顺利。同时,我将努力从幼稚中走出来,变得更加成熟。我的理想将是在现实中追求我的爱与幸福,我永远不会放弃。 再见了,我的公主! 如果有一天,在某个天涯海角,我们有机会相聚,即使是白发苍苍的男人和女人,在那个时候,我希望我们可以成为好朋友来自豪地分享这个记忆,重温年轻快乐的激情。如果这个机会永远没有到来,我希望我是天空中的星星,在你的窗外闪烁。远远地保佑着你,就像一个朋友,每天晚上陪伴在你左右,一同分享甜美的梦亦或是一同经历可怕的梦。 现在问题来了:假定天空是一个平面。所有的星星都躺在它的坐标(x,y)。对于每颗星星,有一个1到100的等级,代表它自身的亮度。其中100是最亮的,1是最暗的。窗口是个矩形,其边缘平行于x轴或y轴。你的任务是告诉我应该把窗口放在哪里,以使窗口中星星的亮度总和最大。注意,窗口边缘的星星不计算在内。窗口可以平移,但不能旋转。

Linode Xen上的Debian/Ubuntu升级Linux 4.9内核开启BBR算法

随着Linux 4.9内核的更新带来了一个新的TCP拥塞控制算法——BBR,该算法解决了几十年来基于丢包来估算带宽的一切算法所导致的在有错误导致丢包的网络环境中带宽降低问题,成为TCP拥塞控制算法的一个重要里程碑。就实际使用而言,在服务器上使用BBR拥塞控制算法可以提高TCP连接在有丢包的情况下所导致的速率严重降低的问题。对于蜂窝数据、不稳定的Wi-Fi、洲际网络连接都有诸多的好处。 BBR: Congestion-Based Congestion Control 然而Linode自己编译的内核却是一个十分精简的版本,并没有包含BBR算法。Linode早几年的机子使用的Xen虚拟化环境是直接从内核启动,在更换内核上有些许小小的麻烦,许多Linux初学者在网上搜索相关资料无果便放弃了。而我认为,作为开发者就应该有阅读官方英文文档的能力,恰好,Linode也提供了一个使用pv-grub更换内核的方式。https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-distributionsupplied-kernel-with-pvgrub/ 相信这个链接已经能解决大多数人遇到的问题了。 接下来介绍Debian/Ubuntu更换发行版内核的方式: 使用wget或curl下载内核的deb包(包括headers和image,纵然不安装headers也能正常使用,但将导致在编译软件包时出现异常),当然你也可以自己编译,这里以Linux 4.9.6 amd64为例:wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.6/linux-headers-4.9.6-040906_4.9.6-040906.201701260330_all.deb wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.6/linux-image-4.9.6-040906-generic_4.9.6-040906.201701260330_amd64.deb dpkg -i linux-headers-4.9.6-040906_4.9.6-040906.201701260330_all.deb dpkg…

调整环境变量在Windows下使用gdb

gdb是一个十分方便的调试工具,不仅仅是对开发者,更是信息学竞赛者的一大利器,使用它在竞赛中往往可以获得更高的调试效率,我们可以轻松地查看到代码执行到哪一行时出现了问题,相比于IDE可以更加快速地输出各个变量的数值来分析程序所存在的问题。 然而许多人却因为不会在windows中配置gdb而望而却步,更有甚者在同时安装了fpc和gcc的电脑上使用gdb遇到了种种问题。这里来说明一下解决方法。 首先,在Windows系统中,对于命令行可以在任意目录直接执行的命令,取决于系统或用户环境变量中path的设置。通俗来说,系统在任意目录下只能直接执行在名为path的环境变量中的文件夹下的可执行程序。 然而,对于大多数OIer而言,所使用的Dev-C++在安装时并不会在环境变量中加上MinGW的安装目录,因此许多人对于许多竞赛书中所讲的gdb的使用一直没有去亲自尝试过。因此,我们就要把MinGW安装目录下的bin文件夹加入到path环境变量中。 首先,在Dev-C++中找到Compiler Options 之后,找到MinGW的安装目录 将这个目录加入到系统的环境变量中 对于XP系统,在“我的电脑”右键菜单的属性中就可以进入这个界面。而对于Vista-10这几个版本的Windows系统中,这个界面则是在系统属性的高级系统设置中。 我们找到用户或者系统的Path变量,然后加入刚才在Dev-C++中所见到的路径,放置于变量值的最前面,然后加上; 特别注意,一定要加上; 比如原来的环境变量是 %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\; 此时应该更改为 C:\Program Files\Dev-Cpp\MinGW32\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\; 之后,再重新打开命令提示符,此时g++、gcc、gdb就可以使用了。这里要提到一点,为什么不把MinGW的目录加在最后。这是考虑到许多人同时有安装fpc,而fpc安装时会加入MinGW的gdb,由于大多数情况下该版本较旧所以可能遇到下图中的情况。 因此,这里把minGW的安装目录放在环境变量的最前面,就是为了让它拥有最高的优先级。诚然,把它放在fpc的目录前面再加上;也有同样的效果。实际上,为了防止改坏环境变量影响系统的正常运行,把minGW放在最后面是比较保守的选择。…

动态规划-01背包问题之我见

背包问题是信息学奥赛中最经常考的动态规划形式,而01背包又是背包问题的基础。除此之外,背包问题还分为完全背包、多重背包等。 01背包定义如下: 对于1个容积为v的背包和n个物品,这些物品分别有自己的体积Vi,和价值Pi,我们需要有一种算法在背包可以容纳的情况下使装入的物品价值最大。此时n个物品不一定全部放入,背包也不一定装满。 与完全背包不同的是,01背包中是n个物品,而完全背包是n种物品,每种物品可多次放入。 这样的问题为什么不用搜索解决呢? 显然,如果搜索可以完美解决这样的问题,我们自然也就不需要用更好的算法来解决问题了。 通过分析问题,我们可知,对于每个物体都有放入背包和不放入背包两种情况,如果我们使用传统的搜索算法解决这个问题,那么时间复杂度为O(2^n),数据大了难免超时。 何为动态规划: 动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。继续分析,我们可以通过递推的方式解决该问题,从问题分析出递推式的方法,便是动态规划。 如何用动态规划高效地解决01背包问题? 这是一个01背包常见的递推式 f[i][j]=max(f[i-1][j],f[i-1][j-Vi]+Pi) 其中,i从1到n,j从1到v,条件为j>=Vi 许多人与我一样,在第一次看到这个递推式的时候都十分困惑,全然不知它的含义。 实际上,f[i][j]就是我们在写动态规划程序时所需要开的一个数组,f[i][j]表示放入前i个物品(包含i,但这前i个物品不一定完全放入),背包容积为j时,背包内物品价值和的最大值。 这样,f[i-1][j]显然就是不考虑放入编号为i的物品的情况下背包内物品的最大价值和,而f[i-1][j-Vi]+Pi,便是在只考虑放入前i-1号物品且背包容积为j-Vi时,背包内物品的最大价值和,再放入编号为i的物品,因此加上Pi,也就得到了f[i][j],即放入前i个物品,背包容积为j时背包内物品的价值的最大值。 对于这个算法,在C语言中通常采用两层for循环解决,以下为C++写法。大家可以根据题目自己修改以符合题目要求。 该方法的时间复杂度为O(n*v)…

解决U盘启动Linux后重启Mac黑屏

今天早上把Mac启动到了我的U盘里的一个Ubuntu系统,做完各项事情后我打算重启返回macOS,我便在重启时等待电脑黑屏后拔下U盘,我之前也是这么做一直没有出过问题,直到今天。 这时听到了Mac开机的“灯”一声,之后屏幕就黑屏了,于是我按住电源键强行关机,之后再开机,可以看到触摸板可以按下并且USB通电了,但是电脑始终没有开机音,屏幕也没有亮,紧张之中,我拨打了苹果中国的400客服电话。 向客服表明情况后,客服让我尝试清除NVRAM,失败,之后让我按住Shift和电源键开机重置SMC,可是忘了让我按Control和Option,显然,还是失败,开机后依旧是USB通电、触摸板可以按下,但没有开机音,屏幕也没有亮。 之后客服就帮我预约了Genius Bar了,好在厦门有Apple Store,但是最近的预约需要8月1日中午。虽然我的数据都有在自己家的服务器上用afp开Time Machine备份,但是并没有什么取出文件的方法,于是我便开始尝试自己解决问题。 几经辗转,我在网上看到了一篇解决Mac开机黑屏问题的文章http://osxdaily.com/2014/11/22/fix-macbook-pro-booting-black-screen/ 按住Shift+Control+Option+Power,只听“灯”一声,成功进入了macOS的登录界面。 祝愿每个看到这篇文章的朋友们都能顺利解决自己遇到的问题。   最后给大家看个笑话

如何理解Linux的文件系统挂载点

对于大多数Linux初学者而言,最痛苦的事情莫过于理解Linux文件系统的挂载点。 我们都知道,在一个硬盘上,我们通过分区把硬盘空间分成几块来使用,在这些分区上可以创建文件系统,而文件系统最终能被访问就需要挂载(mount)。 在传统Windows中,所有分区都被挂载为盘符,比如C:、D:、E:、F:,相当于每一个文件系统都是一个根节点。 而在Linux中,是以一个系统盘为根节点,而其他的文件系统都挂载在根节点下的目录中 仅仅这样说可能对于大多数没接触过Linux的人而言难以理解,现在我们就在Windows中模拟一下Linux的文件系统挂载方式。 不知大家何曾想过,若Windows的26个盘符用完了怎么办?不仅仅是这些带着好奇心的用户想到了,当然,微软也想到了。 在Windows NT中,一种新的分区挂载方式出现,就是把分区作为文件夹挂载在NTFS文件系统中。 这样,原本在Windows应为根节点的分区就成了文件系统根节点中的一个子节点。 我们来到Windows的磁盘管理,查看当前的磁盘分区信息。 可以看到我这里有个256G的物理硬盘,还有一个1TB的虚拟硬盘。 这1TB的虚拟硬盘中,有个99M的ESP分区(当时用DiskGenius随便分的就忘了取消勾选了)。还有三个NTFS文件系统的数据分区。分别被挂载为D、E、F。 现在我们来使用Windows NT提供的另一种挂载方式,将这三个分区的文件系统挂载到C盘的文件夹中。 现在,我们所看到的只有一个C盘(网络驱动器请忽略),并且空间并没有扩大。 但在C盘中出现了3个文件夹,分别对应之前的D、E、F盘的文件系统。当然这里也可以用其它的名称来命名这三个文件夹。 看到这里,相信大家对Linux的目录挂载点有个基本的认识了吧。

StrongSwan IKEv2 IPv6配置

我有了个想法,能不能通过我的Linode,给我的其他服务器和终端设备也接入Linode的IPv6,取而代之当下速度极慢的电信IPv6,毕竟当前电信IPv6用户少之又少,相信广大电信v6用户也都体验过Linux里面把包管理器的源设置成中国各大学的源,然后更新源、下载软件包的速度。 于是,我就给Linode发了个ticket,告诉他我需要更多IPv6地址,不久便收到了回复。 可以看出Linode客服还是非常有礼貌的。这里小小地震撼一下。 现在问题来了,既然/116地址够用,为什么我最后还是选择了/64呢? 我们来看看Linode官方IPv6文档 看到这里,我想到/116地址可能并非路由到自己的Linode上,而是可以通过以太网与该数据中心的所有Linode共享。 既然我们需要搭建一个IPv6隧道,如果通过以太网桥接接入将会有各种各样的问题,既然Linode也说给我们/64的地址段很容易了,我就选择了/64地址段。 之后,我就得到了一个IPv6地址段   好了,现在/64的地址段拿到了,IPv4地址总数量的平方倍的地址段都拿到了,想想也有点小激动,Linode真大方啊。 之后,就开始配置这台IPv6路由器了。 首先在/etc/sysctl.conf里把IPv6转发打开,实现路由器功能 net.ipv6.conf.all.forwarding=1 之后运行sysctl -p使配置生效 这时,我发现服务器的IPv6地址都没有了,只有一个fe80::的Link Local地址。 原来,Linux在开启IPv6路由功能后会关闭IPv6…

在NTFS分区创建swap

迫于学校机房电脑有硬盘保护的无奈(尽管很容易移除,但我们学校毕竟没有专用的信息学奥赛机房,信息技术教室的电脑如果没有硬盘还原将带来一系列问题),我在U盘中分了一个ext4分区安装Ubuntu,然而,在学校机房电脑上登录后系统便卡死不能动弹。我想可能是学校机房电脑内存不足所致,便有了在NTFS分区开swap的想法。 首先,在登录界面上,按下Ctrl+A l t+F1,进入控制台 登录 进入root用户 fdisk -l 看看当前磁盘分区信息 学校电脑真寒酸,1G内存+250G机械硬盘,据说今年暑假要换? 由于机械硬盘最外圈线速度最大,读写速度也最快,考虑到第一分区可能存在大量磁盘碎片影响读写速度,所以我选择了第五分区作为要挂载的文件系统。 用dd命令创建一个大小为2G(128M*16次)的全0文件 mkswap 文件名 swapon 文件名 这样就完成了swap的挂载 再按Ctrl+Alt+F7回到图形界面,输入密码,登录 日常,立于卡顿之世,奏响硬盘之音。 最后,也希望我在信息学奥赛退役之前能见到学校机房换新电脑吧。