浙江省第十四届程序设计竞赛总结

昨天是我第三次参加浙江省赛,比赛地点依旧设置在浙大。上午和其他人一起坐车过去,然后就是都差不多的流程。

由于一些原因,这一次我的两个队友异乎寻常的厉害(高质量就业:阿里研发工程师+京东算法工程师的组合)。赛前内心毫无波澜,不过周神教导我,作为浙财的五队,我们只要保个铜就可以了。

上午9点25左右,热身赛开始。打开试题册看了一下,我们发现热身赛题目跟去年一样,快速通过A和C题。周神机智的想起去年最后一题(输入一个数对一个非常的大梅森数取模,并判断结果的奇偶性)大数据只有四组,通过一番测试之后,今年也是一样。他写了一个程序直接判小的数据,开始枚举最后四组答案的排列组合。我们大概交了10次左右,就发现枚举的地方出现错误,然后改了一下又重新交,最后枚举到13(1101)的时候过了。本着写完热身赛去吃饭的原则,God王让我们开始写B题。不过仔细想了一下发现,万一写完发现是错的,是去吃饭还是不去吃饭,这是个很大的问题。所以,我们直接前往食堂。

12点15分左右,比赛正式开始。我自告奋勇的从A题开始看,本着看样例猜题意的指导思想,我大胆猜想出写法,趁他们两个不注意直接拿起键盘开始写。由于年纪大了,速度更比不上那些年轻人,所以也写了一会儿,交完之后大概有70只队伍通过。之后God王上来平推了B和D。我看一下C题,发现这是个简单题,把题意告诉老王之后,他也很快做了出来。至此,比赛大概过去45分钟。我们写完全部的签到题,完成保的铜的目标。

三个人继续分头看题目,没过多久他们两个人又开始讨论F题的写,很快也想出一个非常巧妙的方法,不过后来发现这个是超时的,所幸God王又想出了线段树的写法。我和周神开始研究E题的写法,很快也验证了用数位DP的正确性,不过也想到这其中有很多细节要考虑。说到这里,不得不讲一下,我昨天晚上就打印了两页模版,其中一个就是数位DP的模版。God王改完F之后,勇敢提交,直接返回了WA。然后我们三个看了好久代码,都没有找出错误来。God王直接出去逛了一下,我和周神开始写E题。God王发现周神读题目没有讲要输出子树的数量,改之就过了。之后,三个人共同推了E。接下来的时间差不多就是在挣扎了,H题God王写来写去都是超时的,G题周神说要找规律,打印了14页数据开始找没多久,就告诉我想的全部是错的。17点14分59秒,God王最后交了一份H题代码,没有什么奇迹,我们结束了这一次省赛。

晚上,在小剧场举行颁奖,这一个环节最主要的就是听听队名。当本科组银奖没有报到我们的时候,我的内心十分的开心。听到第一批金牌也没有报到我们的时候,周神对我讲了一句,是不是下面没有我们,今天就是冠军。事实证明这是幻想,然后他就高高兴兴的上台领奖了,毕竟昨天晚上特意做了一个发型……

总的来说,这次省赛比浙大校赛难了很多,所以写完签到题不要错太多的都可以拿铜。中间过度居然拿了一道数位DP和一道线段树,命题人直接高估了浙江省程序设计的教育水平。最后面的几题,我们三个人共享完题意之后,完全没有思路,其他参赛选手也差不多,完全沦为观赏题。后来想一想,这一份题目只是在错误的时间出现,毕竟比赛的覆盖面是final到专科。但是,我感觉这样的比赛,一个人五小时也能做5题,生不逢时,为什么去年没有这么好的命啊。不过还是要感谢两位大佬带我体验了一下省赛获金的感觉。这一次,同场的还有学军和杭二的高中生,颁奖时,有以为领导还感叹大学生不如高中生。殊不知对于这些高中生来说考上浙江大学都是失败。

不知道明年还有没有机会参加。


C#聊天软件实现

前几天面试,被问如何实现一个类似微信的聊天软件。当时说了一个大概的想法,面试官没有怎么评价,只是最后建议我有空多做一些项目。正好最近不怎么忙,就实现一下。写了一个简易的模型,在这个过程中应用了很多原来学过的东西,当然还有很多问题没有解决。

  1. 这个软件选择C/S架构,所以写了一个服务器端程序和一个客户端程序,然后通信使用的是TCP协议。

  2. 利用socket完成通信,大致的过程如下图所示。


3. 服务器上开两个线程threadListenConnectthreadReceivePacket。服务器上的socket利用bind绑定服务器的ip和端口号。第一个线程死循环监听端口,是否有新的connect请求,并将新的连接socket保存到list中。再利用第二个线程接受客户端发来的数据包,并拆包执行进行相关功能。服务器之后,按照包中的内容判断是否需要发送到其他特定的客户端还是广播消息。

  1. 客户端中开一个线程threadReceivePacket。先和服务器连接,然后利用这个线程接受服务器发过来的数据包。这里也实现了发送给某个特定的客户端和广播。发包和拆包过程和服务器上差不多。

  2. 数据包主要包括发送方ip、端口和接收方ip、端口,以及操作代码。不同的数据段用‘|’分割,接收方也按这样拆包就可以了。

  3. TCP是面向连接的协议,拥有缓存窗口,所以可能会有粘包现象,可能将程序一次产生的命令,分成多次发送。所以数据包里面还要标记一下,我用了’\a’做新的包开始标记,用’\t’做结束标记,如果聊天内容里面有相同的标记的,可以强行转化一下。

  4. 这个程序还可以加上数据库搞出注册以及保存聊天消息,然后自己也没有去写消息的排序以及私聊功能,待做。

  5. 最后相关代码放在github上面

服务器端:

客户端1:

客户端2:


为博客添加返回顶部按钮

适用于WordPress

由于主题没有自带的返回顶部按钮,所以我一直在寻找一种解决方案。之前使用的是wordpress插件提供的返回顶部按钮,后来在网上乱逛,发现有Xnces – 衔铁部落的返回顶部按钮非常的酷炫,正是我要寻找的。于是,我在那个博客下留言询问制作方法。
前几天,看到那个博客上出现了一篇文章-本博客的返回顶部效果
按照上面的方法,折腾一会儿,我也制作出来了,特地记录一下。

  1. 首先,先加载一下环境。在后台functions.php中找到ms_scripts()函数,添加wp_enqueue_script( 'jquery' );调用wordpress默认的JQuery文件。

  2. 我将这个效果有关的js代码放在了主题目录下新建的themes.js文件中。所以在上面的函数中添加下面两句话导入这个文件wp_register_script( 'themes_js', THEMEPATH . '/themes.js',array());wp_enqueue_script( 'themes_js' );

  3. CSS代码我直接加在了主题style.css中。

  4. 重新打开网站就能看到效果了。

themes.js文件中代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var bigfa_scroll = {
drawCircle: function(id, percentage, color) {
var width = jQuery(id).width();
var height = jQuery(id).height();
var radius = parseInt(width / 2.20);
var position = width;
var positionBy2 = position / 2;
var bg = jQuery(id)[0];
id = id.split("#");
var ctx = bg.getContext("2d");
var imd = null;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineCap = "square";
ctx.closePath();
ctx.fill();
ctx.lineWidth = 3;
imd = ctx.getImageData(0, 0, position, position);
var draw = function(current, ctxPass) {
ctxPass.putImageData(imd, 0, 0);
ctxPass.beginPath();
ctxPass.arc(positionBy2, positionBy2, radius, -(quart), ((circ) * current) - quart, false);
ctxPass.stroke();
}
draw(percentage / 100, ctx);
},
backToTop: function($this) {
$this.click(function() {
jQuery("body,html").animate({
scrollTop: 0
},
800);
return false;
});
},
scrollHook: function($this, color) {
color = color ? color: "#000000";
$this.scroll(function() {
var docHeight = (jQuery(document).height() - jQuery(window).height()),
$windowObj = $this,
$per = jQuery(".per"),
percentage = 0;
defaultScroll = $windowObj.scrollTop();
percentage = parseInt((defaultScroll / docHeight) * 100);
var backToTop = jQuery("#backtoTop");
if (backToTop.length > 0) {
if ($windowObj.scrollTop() > 200) {
backToTop.addClass("button--show");
} else {
backToTop.removeClass("button--show");
}
$per.attr("data-percent", percentage);
bigfa_scroll.drawCircle("#backtoTopCanvas", percentage, color);
}

});
}
}

jQuery(document).ready(function() {
jQuery("body").append('<div id="backtoTop" data-action="gototop"><canvas id="backtoTopCanvas" width="48" height="48"></canvas><div class="per"></div></div>');
var T = bigfa_scroll;
T.backToTop(jQuery("#backtoTop"));
T.scrollHook(jQuery(window), "#555555");
});

CSS文件要添加的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#backtoTop{
background-color:#eee;
border-radius:100%;
bottom:10%;height:48px;
position:fixed;
right:-100px;
width:48px;
transition:0.5s;
-webkit-transition:0.5s
}

#backtoTop.button--show{
right:10px
}

.per{
font-size:16px;
height:48px;
line-height:48px;
position:absolute;
text-align:center;
top:0;
width:48px;
color:#555;
cursor:pointer
}
.per:before{
content:attr(data-percent)
}
.per:hover:before{
content:"↑";font-size:20px
}

2016年北京区域赛

今年,一队发挥出色,拿到全部赛区的名额,而且大三也没有多少队伍。所以我们这种弱队还有机会去参加第二场比赛。

作为第三次去北大,流程都是非常熟悉的。周四下午坐Z10出发,第二天上午到达北京。周五下午我一个人去了前两次来北京都没有机会参观的故宫。

故宫之旅并不是很好,主要是游客太多,紫禁城失去了往日的威严。不过,另外加收门票的钟表馆很棒,皇室的藏品居然如此花哨。有些钟表的滴答声一百多年之后依旧飘荡在场馆之内。出了故宫之后,走了半个小时才找到一个地铁站,这个设计非常的愚蠢吧,之后就动身前往北大。

周六下午热身赛,我们出来的比较早,在体育馆的看台上做了一会儿,看着下面排列整齐的两百多台电脑,心中生出一丝感动。之后就是进入场馆搞事情,电脑是五位数的戴尔移动工作站,外接了鼠标、键盘、和显示器。和我自己在寝室里面干的差不多。海巨表示显示器大看着爽,不过也发现键盘上有日文符号,这就比较影响我的发挥了。然后是例行看一下 周围的队伍,前面是北师、后面是北航、右上方有杭电一队,感觉压力又好大,虽然他们根本不会在乎我们。

比赛开始之前,队友想起在大连时,我讲了一句热身赛只要看一下AC是什么颜色就好了,最后被我成功奶死,全部是WA,所以告诫我不要乱说话。拿到题目之后,我们看了一下,发现题目是前几年北大出的区域赛和网络赛的。其中B题还是我们前几周训练过的题目,我拿起键盘表示这次终于有机会拿个一血了,马上写了起来,队友还是表示不相信。当我写完提交后,邪恶战胜了正义,果真发挥了一个WA,此时其他有一个队伍拿到这题的一血,彻底骨折。所幸改了一下还是过了,之后C题也是原来写过的,上去写了一下就过了。之后就讨论了一会儿A题,不过没有得出什么答案,感觉暴力上去肯定会超时,D题也不会写,最后上去让海巨测了一下机器和各种返回就去吃饭了。晚上回去才发现A题比我们想的还要暴力,没有勇气啊。

由于我们知道不会来北大吃太多餐,所以晚饭比较丰盛。一遍吃一遍感叹北大的伙食真好,早知道原来好好读书了。回到宾馆后,海巨在找题目写,翔哥想着阴阳师靠他的符偷渡欧洲,我看着炉石直播学习技术。又是一天。

周日,因为经费紧张,住的宾馆离北大比较远,我们三个7点就出发了,8点半左右到达北大赛场,然后等待比赛的开始。

9点比赛正式开始,开场顺利的写完了两道签到题,然后我们看了一下一道搜索题,我感觉可以写了,另外两个人去看了一下I题。我写差不多后,海巨上来写了I,也很快的写完并提交了,不过返回了WA。换我上去继续写搜索题,很快我写的超时了,只好改的优雅一点,翔哥也指出海巨理解错了题目,他们两想了一下决定帮我一起改搜索题,小改了一些东西之后,又提交了两次,返回两个WA。当时我们很紧张了,不过没有办法,海巨在看代码,我在写最暴力的准备对拍,翔哥在那里构造数据。最后,翔哥构造出了一组强力的数据,成功把我的代码hack了,我发现改掉一点就会对,不过没有想明白怎么回事,就改了一下记录答案的方式,最后自信的提交返回AC。然后我们将目光聚集到了K题,这个破题,题目就看了好久才明白,不过数据范围居然有10的100次方,我们搞了好久才都没有想出来,我感叹了已经上次在大连也是死在这种恶心的题目上,还是要想,我们写了一个10的9次以内的暴力程序打表,神奇的发现最大符合要求的个数只有样例给的83个,然后他们开始推规律,我在那里划水。想着写不出来,只要让海巨上去写一个只要83个答案表的程序,赌一发梦想。虽然感觉北大不会蠢到把最后一个答案告诉你,海巨还是写了,不过交上去还是WA。之后就陷入了江局,封榜后一会儿,我算了一下发现15位数随便填的情况下1就有10的16次左右个了,果断抢来电脑,不知道是什么力量让我点开海巨WA的代码,我看了一下差点吐血,找一个最大不超过n的值被写成立找一个最小超过n的值,我问了一下海巨,他还不知道,我直接改了一下就交上去,再赌一个梦想,然后就AC。我们马上点开排名,不过只能现实封板前的排名103,这题交了应该会前进一些,但是北大只有93个奖牌。海巨表示把I题写了才能稳,我看了一下I题,果断表明我不会数学题,只能靠你们了。然后实力分析一波之后,感觉要ntt操作,找了一下发现没有带这个模版,只好告诉海巨要么你想个其他的方法,要么自己创造一个ntt算法。我也没有找到其他组说的图论题是哪一个,只好提前选择死亡,吃起了发的午餐,果真像赛前说的一样吃东西就等于放弃了,最后还有10分钟结束的时候,我们三个人都愉快的吃起了午餐,把自己的命运交给其他小笨蛋来掌握。边吃边感叹这是第一次在正赛封榜后过题以及终于不是什么题数靠前的队伍了。

比赛结束之后,不知道结果怎么样,我们只好在那里等待,这要是在之前可以直接会师火车站了。北大搞了一堆事情,才开始滚榜,判完我们题目的时候好像跳到了81名去了,他们两个开始统计超过我们的人,又过了一会儿,发现最后名次固定在了85名,然后三个人都好高兴。滚完铜牌区之后,开始颁奖,我也有幸登上北大的领奖台。之后,那些也和我们没有什么关系了,反正两年多的努力有了回报就可以。

从北大出来,直奔麦当劳买了一下晚餐就去火车站了。我特地点了一杯拿铁,稳如拿铁。还是要相信科学。


为知笔记写博客测试

适用于WordPress

如果你可以看到这一篇文件,就表示我测试成功了!

tips:

  • 为知笔记中的标签自动变成博客文章的标签
  • 选择发布时,会自动检测是新发布文章还是修改文章
  • 自带markdown优化,轻松解决wordpress没有什么好用markdown编辑器的问题

参考连接:发布笔记到博客,更好的博客离线撰写工具


iPad Pro 开箱

好久没有更新博客,差不多都忘记 hexo 的指令了。
上周六在苹果官网订了 9.7 英寸 iPad Pro WLAN 32GB - 金色 ,前几天刚好到了,所以写一篇庆祝一下。


杭电OJ AC500题

距离AC400题,过去了135天。

有很多出去的学长学姐都是不知道把红宝书背了多少遍,又一次和XX聊天,他说我打赌你背的有些单词,你一辈子都不会用上,但是尽管如此,很多人都背下来,这就是毅力,就是韧性。有的人放弃了,有的人却坚持下来,不得不承认,只有耐得住寂寞的人最后才会成功。学习是一项孤独而崇高的事业。


只是为了好玩——Linux之父林纳斯自传

  1. 这个是我为了学习Linux操作系统,而从图书馆精心挑选的书。
  2. 林纳斯眼中的人生意义:生存、社会秩序和娱乐。
  3. Linux起源于林纳斯对于Minx的不满足,壮大于开源运动。
  4. Linux也是世界上最大的开源协作项目。
  5. 内容和题目一样,不过也没有太多有趣的故事。
  6. 林纳斯的思想朴实情切,不高深。
  7. 至少读完之后,你会了解到没有他那样的基础和机遇去创造新的操作系统。
  8. 书中出现了例如微内核、分页管理等计算机组成原理中的名词。
  9. 现在已经不能说出这些具体含义了。
  10. 希望有一天可以去看Linux源代码。