不当伸手党,从抛弃百度开始

原文链接:微信 知乎 转载请联系原作者授权

有个群里的同学给我反馈,“伸手党”这个词不能滥用,不然很伤人。我虚心接受这个反馈。古人讲闻道有先后术业有专攻,不能因为人家问的问题我觉得很简单就说人家伸手党,这对人不厚道。

但是真的就有很多伸手党……比如某群里有人问某某书有没有电子书,唉,我就先不说传播盗版电子书很不地道吧,这种电子书不是找找就有么,为啥要在群里问?

伸手党伸到这个程度,我也真是没话说了……

(顺便说啊,www.justfuckinggoogleit.com 这个网站真的可以解决超多问题,拿走不谢😏)

然后JIRA群的WJ同学遇到了技术问题,在MySQL上面装JIRA报了错,在群里贴了个stack trace,半天也没得到答案。我扫了一眼,看见这么一句

我真的是连脑子都没过,就等滴滴车到的一分钟里搜了一下,

这答案就摆在搜索引擎第一条的问题,非要这么问,到底是图个啥?我感到非常困惑。所以我就问了WJ同学。WJ同学给我的答案是:

百度了 但是关键字不对 的确没搜到您这个
WJ同学

于是我突然意识到,还有很多同学不知道一个基本的事实:

百度不是搜索引擎!
百度不是搜索引擎!!
百度不是搜索引擎!!!

(重要的事一定要说三遍!加黑!加大!加咆哮体!)

不信的话可以自己实验一下。我用同样的关键字“jira mysql app_user select command denied”在百度搜了一把,我有两个观察。

第一,百度完全不搜任何英文网站,尽管我输入的都是英文。

第二,因为它完全不搜任何英文网站,它的结果来源……好吧,没有对CSDN不敬的意思,毕竟我也是CSDN的老员工,不过读者可以打开第一条搜索结果看看,自己评判一下,这位同学有把问题讲清楚的能力么?

这就是百度的搜索能力。如果世界上只剩下百度这一个搜索引擎,我可能也解决不了WJ同学的这个问题。(当然更可能我会直接去StackOverflow和Atlanssian官网,总比用百度好。)

百度不是搜索引擎!(重要的事再说一遍)

百度按照别人付多少钱来判断把内容放在搜索结果的什么位置。这个东西不叫搜索引擎。这个东西张朝阳2000年就做过了,叫分类目录。在搜狐之前还有个更牛逼的分类目录网站,叫雅虎。2001年的时候雅虎被一家做搜索引擎的公司给严重打击了,这家公司叫Google。

百度开了历史十八年倒车,还好意思说自己是Google的同行?

所以啊,搞技术的人,怎么能开始靠谱起来呢?第一步就是,从现在开始,别再用百度了。就算你不知道怎么科学上网(当然我很想说,连科学上网那点困难都懒得解决,这搞技术也没啥前途),Bing也可以用用。

就,Bing起码是个搜索引擎。只要是个搜索引擎,90%的技术问题都还是能找到答案的。一般来说答案就在第一页。比如说,前两天我还说一个同学伸手党,是怎么回事呢,这个同学问,“学DDD看哪一本书比较好”,我说我最喜欢这种问题了。

答案就在第一条,还给你大图,生怕你看不清。但凡只要是个搜索引擎,基本上都这效果。

然而,百度不是搜索引擎!!!

你和大神之间的差距,很可能只是你用百度。


08年的金融危机究竟发生了什么

次贷危机是什么?

是一场全球性的金融溃败。意味着这些你听过的名词:次级贷款、债务抵押债券、信贷市场冻结、以及信用违约掉期。

谁会受到影响?

所有人。

这是怎样发生的?

是这样的。次贷危机拉拢了两群人:房主和投资者。房主就意味着房贷,投资者意味着资金。房贷就等于房子,资金则等同于大机构,比如养老金基金,保险公司,主权基金,共同基金等等。这些机构通过金融系统联系在一起,也就是一帮银行家和经纪人,被通称为“华尔街”。与看上去不同的是,华尔街的银行紧密地关联着民生街(main street)的房子。

现在从头开始讲事情的起因。

很多年前,投资者们坐在钱堆上,寻找好的投资机会来赚更多钱。习惯上他们会去找美国联邦储备委员会购买短期国债,这被认为是最保险的投资。但是,由于互联网泡沫破灭和911事件,美联储主席格林斯潘将利率降低到1个百分点来维持经济增长。投资者说,1个百分点的回报率太低了,不用,谢了。但从另一个角度讲,这意味着银行能够以1%的利率从美联储借款。再加上贸易顺差从日本,中国和中东不断涌入,所以有大量的低息贷款使银行借贷轻而易举。于是他们疯狂地使用——“杠杆”。

“杠杆”是用借贷来扩大交易收益的手段,它是这样操作的:某人的一笔普通交易,用自己的1万美元买了1个箱子,然后以1万1千美元卖给其他人,净赚1千美元,这桩买卖还不错。但如果用杠杆操作,一个有1万本金的人,会去再借99万美元,现在他手里有了100万美元,可以买100个箱子。用掉那100万美元以后,再以110万卖给其他人,还掉99万贷款本金和1万利息,除开最初的1万,他净赚9万美元!而另一个人只能赚1千美元。杠杆能把不错的买卖变成不凡的交易,银行也就是这么赚钱的。

因此,华尔街借入大量的信贷,做了许多大生意,赚的盆满钵满,最后还掉本金。投资者们看到以后也想分一杯羹,于是华尔街就想到了他们可以通过利用房贷拉拢投资者和房主。是这样的:有家人想买房子,他们要存足够的首付,和房贷经纪人联系,这家人通过房贷经纪人找到房贷公司,房贷公司给他们房贷,经纪人拿到佣金,这家人买到房子,成为房主。这对大家都很好,因为房价事实上永远在上涨,一切都太完美了。

有一天,房贷公司接到投资银行的电话,他想买下房贷。房贷公司用一个不错的价格卖给他,投行的银行家借到数以百万计的资金,然后买了成千上万的房贷,放到一个漂亮的小盒子里。于是乎,每个月他就可以得到盒子里房主还的房贷,然后他召唤“银行巫师”施展“金融魔法”把房贷分成三部分:安全、还行、有风险,分别放到盒子里,取个名字叫“债务抵押债券”,简称CDO。

CDO像三个小瀑布一样工作。当资金回笼的时候,最上面的盒子先装满,再流到中间盒子,剩下的装到最底层,资金来源于房主偿还的房贷。如果有人欠贷不还的话,那回笼的资金就少了,最底层的盒子就装不满了,所以最底层的盒子风险最大,而最上层则更安全。为了弥补高风险,底层盒子的收益会更高一些,而顶层盒子的收益更低,但也还不错。银行还给顶层盒子套上保险,这叫“信用违约掉期”。做这一切是为了让信贷评级机构把顶层认证为3A安全投资,是安全性最高的评级;中间盒子评为3B,也还行;风险最高的部分就懒得评级了。

有了3A评级,投行的银行家可以把最安全的部分卖给承担低风险的投资者,还不错的卖给其他银行家,把最有风险的部分卖给对冲基金和其他风险投资者。投行银行家赚了几百万,最后还掉贷款。投资者终于为资金找到了好的出路,这可比1个百分点的短期国债好多了。投资者很满意,想买更多的CDO。于是,投行银行家找到房贷公司,想买更多房贷,房贷公司找经纪人要更多房主,但经纪人再也找不到买房的人了,能申请房贷的人都已经有房子了,但他们有个主意:在房主付不起房贷的时候,房贷公司就收回房子,而房子总是在升值,因此房价已经覆盖了断供的风险,房贷公司只需提高新房贷的风险,而不要求首付,不需要收入证明,不需要任何手续,他们也真就是这么干的。不是借款给值得信赖的房主,也就是所谓的优级贷款。他们开始找那些,嗯……不那么可靠的人,于是就出现了次级贷款。

转折点出现了。

经纪人和往常一样,用房贷拉拢了这家人和房贷公司,拿到佣金。这家人买了一所大房子,房贷被房贷公司卖给了投资银行家,又被包装成CDO卖给了投资者们。一切都很顺利,大家都发财了。只要能把房贷卖给下家,自己就不用担心了,让下家去操心好了。如果有房主还不起房贷,没关系,只要能把风险转嫁给下家,自己就能赚几百万,就像在抱着定时炸弹玩击鼓传花。

毫无悬念,房主还不起房贷了,而房贷在银行家手中,这就意味着,他无法偿还月供,房贷变成了房子。没关系,他还能选择卖掉房子。但是越来越多的月供都变成了房子,市场上待售的房子越来越多,供应远远大于需求,房价就再也不会上涨了。事实上,房价开始下挫。这对仍在还月供的人来讲,就形成了一个有趣的局面。他们邻居的房子都挂牌出售的时候,自己的房子也跟着跌价。那为什么还要偿还30万的房贷,而自己的房子只值9万美元?他们觉得继续还贷毫无道理,即使他们还得起房贷,他们也弃房而去。

断供潮横扫全国,房价跳水,现在投行银行家手里只是一批跌价了的房子。他给投资者打电话推销CDO,但投资者也不傻,他们答道“不用,谢了”。他也知道,一滴资金流也没有了。银行家开始向所有人推销,但谁都不愿意买他的炸弹。他现在惶惶终日,借了数百万甚至借了数十亿才买下这些炸弹,现在却还不起了。不管他怎么折腾,就是无法脱手。但他并不孤独,投资者们自己也买了成千上万的炸弹,房贷公司在打电话想卖掉炸弹,但银行家根本不会买,经纪人则被炒了鱿鱼,整个金融系统被冻结了,黑暗时代到来了。大家都破产了。

这还没完,投资者找到房主,告诉房主他的投资已经一文不值了,现在你看到危机是如何轮回的了。

欢迎来到:次贷危机时代。


美国往事(超哥)分析准确率报告

我研究了美国往事(超哥)的150篇文章,以此来分析超哥预测的准确率。

本次研究所有的样本数据来源于超哥的知乎文章,且仅选取正文,忽视评论区、微信公众号与知识星球等的互动。其中,第70、92、118三篇已无法浏览。在剩下来的147篇中,每篇我找了5个没有炒过比特币的人进行阅读,让他们提取出超哥对比特币价格的基本观点,以原文为主。在所有的基本观点整理完之后,由我来对照Trading View上的Coinbase交易所的BTC走势,总结后市情况,并与基本观点对照,分析吻合情况。吻合情况分为三类:吻合指分析的数据与后市走势基本一致,具有很重要的参考意义。大致吻合指的是成功分析出了涨跌方向,但目标点位与实际情况略有出入,或分析会使人踏空等等。不吻合指分析与实际情况相反,或目标点位与实际情况有较大出入等。由于分析判断全由我一个人进行,难免有主观因素存在,仅供参考。

在可以浏览的147篇中,与实际情况吻合的有85篇,占比57.8%。大致吻合的有30篇,占比20.4%。考虑到大致吻合的文章也有很强的参考意义,与吻合的合并共占78.2%,是非常不错的准确率。不吻合的共有32篇,占比21.8%。

在所有不吻合的文章中,大多数出现在下跌趋势中。也就是说,在2017年9月和2018年的熊市中,超哥表现地略微过于乐观,毕竟,谁都不会想到比特币会从20000跌到3000。

如果对这篇报告有什么意见或疑问,欢迎在博客的评论区回复。

下一篇分析哪个大V,由你们说了算。

本篇报告耗费了我大量的时间和精力,如果读后有收获的话可以点击这里请作者喝咖啡

以下是源数据(手机端显示不全请切换桌面版网站):

序号 发布日期 基本观点 后市情况 吻合情况
1 2017/9/2 预计过不了多久,价格会寻求突破34000-35000。 持续下跌直至9月15日。 不吻合
2 2017/9/4 大概率上还是会尝试去突破5千美元这个槛,突破以后就会迎来更大的调整了。 持续下跌,未能突破5000美元。 不吻合
3 2017/9/5 价格不是谷底,继续等机会。 持续下跌直至9月15日。 吻合
4 2017/9/6 大概率可以见好就收了,先拿好这20%的利润观察观察吧。 达到短期最高点后持续下跌直至9月15日。 吻合
5 2017/9/8 耐心的人可以再等两天,不耐心的可以入场。 接下来的一周跌去1000美金。 不吻合
6 2017/9/9 反弹了高位必须必须快速出货;等待消息落实;拿住利润;不然就什么也别做,静观其变。 持续下跌直至9月15日。 大致吻合
7 2017/9/10 如果真的关掉交易所,价格会还有一波大跌的。 持续下跌直至9月15日。 吻合
8 2017/9/12 弹到开始接近过去48小时最高点的时候,依个人情况逐步抛出。 未能回到最高点。 不吻合
9 2017/9/13 对国外价格而言,首先会去试探3500美元这个点,之后就是3000美元这个点;国内价格而言就是对应的23000和19000左右;没跌破某个点,就会在某个点附近震荡反弹,跌破了就继续往下走。 9月15日最低价2975.01美元。 吻合
10 2017/9/14 今天之后的行情,估计还是会震荡下跌的,如果就怎么阴跌下去,就等着吧;如果突然某个时间点出现大的下跌(不是因为政策),跌到了23000这个点甚至,那么今天的低点就会出现在这附近。 次日跌至2975.01美元后拉升。 大致吻合
11 2017/9/15 关了一个交易所,价格就从昨天的24000跌倒现在的19000,再关一个价格会去试探15000,继续关掉三大的最后一个价格会间断性去试探10000。 震荡上升。 不吻合
12 2017/9/16 虽然今天价格反弹了,但过了这个反弹大概率最后还是要回去测17000这个点的。 次日最低价3475.64美金。 吻合
13 2017/9/18 如果近期想抄小底的,就像2天前在上一篇文章里说的,比特18500以下,莱特250左右开始,以太坊1250左右都是小底,可以轻仓操作。 9月22日达到最低点3509.79美金。 吻合
14 2017/9/19 现在回落就是买入机会了,不论大小回调,也不用管国内关交易所,抑或者其他乱七八糟的打压政策,越出政策越买入;从此以后中国的政策都是买入机会了。 9月22日达到最低点3509.79美金后持续上涨。 吻合
15 2017/9/20 大概率会在震荡以后向上走。 9月22日达到最低点3509.79美金后持续上涨。 吻合
16 2017/9/23 现在开始回落去测试下方20000-22000这个底,个人认为这个底还算是牢靠的。 持续上涨。 吻合
17 2017/9/23 如果这一次反弹可以有效的突破23500,甚至迫近24500,那么这一轮的反弹就给出一个信号,那就是可以暂时长期持有的信号;不需要再高点抛出,因为高点可能还在上方,如果没有迫近23500甚至连23000都没有过,那说明暂时不会冲上新高,抄底的可以出手套利了; 9月26日突破成功。 吻合
18 2017/9/26 仍然停留在大的回落买入的行情里。 后市震荡上升。 吻合
19 2017/9/28 只要站稳了26500以上,那么28000虽然有压力但是会破掉的,如果今天不能站的住26500,并且跌回到25500,那就得等着下跌再买入了。 站稳且后市震荡上升。 吻合
20 2017/9/29 我们可以预见接下来在这个位置待一些日子后,会去冲30000这个点,只要后续不遇到大的利空影响,冲30000不是个难事。 10月9日成功突破。 吻合
21 2017/9/30 这一波向上上涨的周期很有可能会使比特币直接突破历史新高直接冲破35000大关。 10月12日突破。 吻合
22 2017/10/2 这一波上涨到目标位置应该是在35000,31000-32000附近可能会有短期的震荡,但应该问题不大。 10月13日至10月28日在35000元上方震荡,后继续上扬。 大致吻合
23 2017/10/4 现在的价格是28500,应该在这个附近震荡不会超过两天。之后会继续往上走,下一波会在31500附近又遇到小压力位。 震荡2日后开始上扬。 吻合
24 2017/10/6 下方在26500这个位置支撑很强,这一轮周期且不会破掉。 10月14日前持续上扬。 吻合
25 2017/10/7 拿好之前建的仓,等突破了这个震荡区我们伺机而抛。 10月14日前持续上扬。 吻合
26 2017/10/9 上方的第一个小压力位置在31000,过了这个压力位置35000这个历史新高就没大问题了。 10月9日突破后在10月12日达到35000。 吻合
27 2017/10/10 上方将去试图破掉35000(5400美元)。 10月12日突破。 吻合
28 2017/10/12 35000(5400美元)没大问题。 当日突破。 吻合
29 2017/10/13 如果破掉站稳了6000美元,上方还有一个这一波周期的极限位置就是7000美元。 10月29日突破6000美元,11月8日最高达7898美元后回调至11月12日的5511美元。 大致吻合
30 2017/10/14 比特币大概率还有一波上涨,就是继续冲上40000(5900美元)。 10月20日突破。 吻合
31 2017/10/15 后续一定会再一次上40000的。 10月20日突破。 吻合
32 2017/10/17 大概率仅两天就会再拉一波到40000(USD5900)以上。 10月20日突破。 吻合
33 2017/10/18 下方第一个支撑位在5400美元(可能是37000-36500RMB),第二个支撑位在5000美元(34000RMB附近吧)。 当日最低价5102美元。 吻合
34 2017/10/19 比特币的第三个支撑位置在4400美元附近。 当日最低价5529美元。 不吻合
35 2017/10/21 选择搭建出货位置。 当周最高点6189美元,但10月25日起开始上涨。 大致吻合
36 2017/10/25 比特币会迎来该有的调整和横盘。 从当日开始持续上涨至11月8日最高达7898美元。 不吻合
37 2017/10/25 要等着价格回到5500美元以下再考虑。 除当日最低价5376美元外未能到达5500美元以下。 不吻合
38 2017/10/27 等到5500美元以下再考虑入场。 未能回到5500美元以下。 不吻合
39 2017/10/28 短期我会继续等5500美元以下再考虑是否操作。 未能回到5500美元以下。 不吻合
40 2017/10/30 想入场就是要么等稳定6200美元立即入场,要么就是回调5500美元附近入场。 10月31日突破6200美元,但此时已踏空。 大致吻合
41 2017/11/1 再次分叉前会去冲击7000USD大关。 从当日开始持续上涨至11月8日最高达7898美元。 吻合
42 2017/11/3 接下来调整的幅度可能也不会很大了,能到6600就是短期的调整点位。 11月12日调整至5511美元。 不吻合
43 2017/11/5 比特币会在分叉前上8000。 11月8日最高达7898美元。 大致吻合
44 2017/11/8 等到分叉完后再入。 11月12日调整至5511美元。 吻合
45 2017/11/9 比特币预计会在高位震荡一段日子(6800以上),这段日子是其他所有币这一周期里最后的大涨机会。再往后调整真的来了,所有币都躲不过大调整。 次日便跌破6800美元。 不吻合
46 2017/11/11 跌破下方是6200。 11月12日调整至5511美元。 不吻合
47 2017/11/13 接下来比特币再次碰到5000这个点之后,将会结束调整,月底就反弹,进入12月份和2018年初价格最高会是10000-13000。 当日即开始反弹。 大致吻合
48 2017/11/17 下一轮就是破10000。 11月29日成功突破。 吻合
49 2017/11/21 稳住现在的8200,上方的第一个压力位置在8800,稳破第一压力位置8800,上方第二个压力位置在9600, 然后稳住9600,就是轻轻松松破10000美元大关了。天花板在13000附近。 11月26日突破8800美元,27日突破9600美元,后持续上涨最高达19891美元。 大致吻合
50 2017/11/24 大概率还是会回到8200附近的。 次日即突破8200。 吻合
51 2017/11/25 现在BTC在8200附近蓄力,一旦稳住了上方8800, 9600, 10000都不是问题,天花板在13000附近。 11月26日突破8800美元,27日突破9600美元,后持续上涨最高达19891美元。 大致吻合
52 2017/11/26 稳住此位置,上方继续是9600,破10000不成问题,可能会在11000遇到强阻力,天花板在12900-13000附近。 27日突破9600美元,后持续上涨最高达19891美元。 大致吻合
53 2017/11/27 10000-11000之间没有大的阻力位置, 下一个阻力位置在11200左右,然后去冲击13000附近,然后会迎来一个比较复杂的情况。 持续上涨最高达19891美元。 大致吻合
54 2017/11/28 稳住9600是大概率事件。 成功稳住。 吻合
55 2017/11/29 破万之后上方第一个点是11000,想出货的建议把战线拉长一点,再上方是顶部12900附近。 持续上涨最高达19891美元。 大致吻合
56 2017/11/30 昨天恋战没出的,切不可以在行情大跌中出货。 持续上涨最高达19891美元。 吻合
57 2017/12/1 9000-10000,不可以动,8600是大支撑,要么等到这个附近再抄底,要么等到稳住在10500再入。 当日最低价9517,最高价10937,按此策略会踏空。 大致吻合
58 2017/12/2 下一拨就是12900附近。 12月6日头也不回地破了。 不吻合
59 2017/12/6 12900应该就是这一波周期暂时的顶部了。 12月6日头也不回地破了。 不吻合
60 2017/12/7 现在的行情就是在冲向15000。 当日最高价19697。 不吻合
61 2017/12/8 如果不能稳住15000,第一个支撑位置在12500附近,第二支撑位置9600。 12月10日达短期最低价13501。 吻合
62 2017/12/11 价格回到13000附近就要开始再次入手了。震荡调整完毕后,比特币将会面临上方第一个小阻力位置17000(可以忽略这个位置).真正面临的第一个压力位置是21000, 再下一个压力位置是25000,目标位置是32000。 当日最低价15200,震荡上升至12月17日的19891后回调。 不吻合
63 2017/12/12 比特币将会面临上方第一个小阻力位置17000(可以忽略这个位置).真正面临的第一个压力位置是21000, 再下一个压力位置是25000,目标位置是32000。 震荡上升至12月17日的19891后回调。 大致吻合
64 2017/12/13 比特币将会面临上方第一个小阻力位置17000(可以忽略这个位置).真正面临的第一个压力位置是21000, 再下一个压力位置是25000,目标位置是32000。 震荡上升至12月17日的19891后回调。 大致吻合
65 2017/12/15 比特币将会面临上方第一个小阻力位置17000(可以忽略这个位置).真正面临的第一个压力位置是21000, 再下一个压力位置是25000,目标位置是32000。 震荡上升至12月17日的19891后回调。 大致吻合
66 2017/12/19 接下来就是21000。 回调至12月22日最低10400。 不吻合
67 2017/12/21 BTC上方的位置不会变的,仍然是17000,21000,25000,32000。 2018年1月6日最高达17174。 吻合
68 2017/12/23 想要继续上涨,就必须不能再跌回12500以下,不然就是行情继续下跌到9600。 12月30日最低至12500后上涨。 吻合
69 2017/12/27 上方位置仍然是17000,21000,第一目标位置25000,第二目标位置32000。 2018年1月6日最高达17174。 吻合
70 2017/12/30 文章被建议修改:违反知乎社区管理规定。 - -
71 2018/1/3 如果能稳破15800意味着大涨就来了,如果不能还是得回去继续蓄力。 1月5日突破后,7日开始回调。 不吻合
72 2018/1/4 如果比特币能稳稳的过了15800,起码预示着比特币要涨了,如果不能那就继续在15000附近震荡。 1月5日突破后,7日开始回调。 不吻合
73 2018/1/7 上方17000已经在靠近,能稳住不回落就会直接开往下一个位置21000,然后25000又很关键. 是能否实现32000的关键。 当日开始持续下跌。 不吻合
74 2018/1/9 这之后我们继续盯15800这个点,和之前一样,过了这个点,上涨继续,过不去,那就得在15000附近继续蓄力。 未能过,持续下跌。 不吻合
75 2018/1/12 一旦12500被有效跌破,中间有个小支撑在10800附近,然后就得回到9600。 1月16日跌破12500,1月30日跌破10800,2月1日跌破9600。 吻合
76 2018/1/15 对于比特币最关键的点继续在12500,这个点被有效跌破,那就是熊来了,没办法。 1月16日跌破12500,1月30日跌破10800,2月1日跌破9600。 吻合
77 2018/1/18 接下来继续刷一波就得刷到8100附近,如果政策特别狠的话,大底可能在6800,政策不狠那就在8100,如果没政策,那9600附近就差不多到底了。 2月6日最低达5873。 大致吻合
78 2018/1/28 下一轮的起点会在12800。 未能达到12800。 不吻合
79 2018/2/1 要是砸破了9600,我们只能去8100-8200去找比特币了。 2月6日最低达5873。 大致吻合
80 2018/2/3 8100不能继续撑住的话,继续向下探底6800甚至6000附近。当然这一波大跌完了,应该会歇一歇了,周末应该会尽力尝试突破10000, 然后再开始下一波大跌。 2月6日最低达5873。 大致吻合
81 2018/2/6 如果今天和明天的反弹不能过去48小时最高点的话,继续跌,下一波往哪儿跌?6800都被跌穿了,那下一位置只能去找5400了。 反弹突破高点回弹。 吻合
82 2018/2/10 下一波的回调不跌破6900-7100这个位置(举个栗子,比如周末反弹到了9600然后一个回调跌到了7800,但是急速反弹了,那么就是成功了!!),那么就进入了可以买入并且长线持有的阶段了。 2月20人最高达11775。 大致吻合
83 2018/2/14 突破9200,会向上探一次短期顶11900,跌破7800,那么我们会再一次看到7000以下的比特币。 2月20人最高达11775。 吻合
84 2018/2/18 只要别跌破9600就不会有事,跌破了那就说明熊市仍然继续,探底仍然再继续,不跌破而急速反弹就是牛市前的信号了。 2月26日急速反弹,但牛市没有来临。 不吻合
85 2018/2/23 最重要的就是9600这个位置能否有效了,不能有效那么就得去8100附近去找比特币了,比特币要是连8100这个位置都无法守住的话,那熊市的大底就比上次的5600还要低。 3月5日起回调。 吻合
86 2018/2/27 比特币会在10800遇到些压力,过了10800的话会本月第二次冲击11900-12500这个灾区。只有过了这个灾区,牛市才能来到。下方的话9600破了没什么意义了,小调整估计还能撑一下,但是继续大跌的话只能直接回8100找去了。 过10800后最高11645。 吻合
87 2018/3/3 接下来估计会继续发起新的冲击,如果顺利冲破的话,会继续冲击上次给出的第二个灾区,11900-12500。 最高11645。 吻合
88 2018/3/9 这一套组合拳利空终于将大饼砸破了9500-9300这个上一次筑起来的支撑位置,今天不能尽快站回去这个位置的话,大饼回去8100-8200的几率会变的很大。 3月14日跌破8200。 吻合
89 2018/3/15 不能有效的反弹,那么行情稳一稳之后继续跌,而下一个位置得跌回6900-7100附近了,不过我对这个位置没抱有很大期望。 3月29日跌破7100。 吻合
90 2018/3/21 上方的话9200-9300会有一个阻力位置,这个位置可以过去的话,会直接攻10200。再往后再攻11900-12500这个灾区(那将就是第三次了)。 未能突破阻力位置。 吻合
91 2018/3/28 大饼下一个点位就是6900-7200了,这个地方是可以提供一些支撑的,跌到了至少也会在此出反弹。 4月10日起反弹。 吻合
92 2018/3/31 文章被建议修改:违反知乎社区管理规定。 - -
93 2018/4/5 能重回7000的话就会继续试图冲击站稳7300-7400,目前来看,出现行情反转的信号一个都没有,所以所有的上涨都是反弹不是反转。 4月10日起反弹。 吻合
94 2018/4/15 如果最后仅仅是在8300附近或者下一给位置9200附近就掉头继续下跌的话,那么熊市才走了一半而已,市场还会继续冷却直到价格波动很小,直到绝大多数人彻底离场才会开始反转。如果从6800站到8300,再站到9200,再稳稳的站到11900-12500附近的话,那么大牛市就会被正式来了,那么到时候过去的2万美元的历史最高价将会变的很廉价。 最高达9948。 大致吻合
95 2018/4/25 回调不破8800甚至8200那就是继续蓄力为下一波上涨做准备,直接跌破了那就走人吧,下一波大跌就来了。 5月16日跌破8200。 大致吻合
96 2018/5/5 我觉得接下来这一次碰面牛赢的概率非常的大!!一旦赢了,11900-12500就是个小山坡和起点而已。 次日开始下跌。 不吻合
97 2018/5/10 目前回调是正常和健康的,回调不破8800都没问题。 次日跌破8800。 不吻合
98 2018/5/17 大饼破掉8800后,接下来要试探8100了, 这个位置一旦有效跌破就会继续回到7200-7300了,这个位置我相信暂时还是能抗住的。 22日跌破8100,6月10日跌破7200。 大致吻合
99 2018/5/21 只有站稳8800才能继续往上走,否则就只能在7900-8800之间震荡。 5月23日跌破7900。 吻合
100 2018/5/23 7900撑不住会去往6900-7200附近。 6月10日跌破6900。 大致吻合
101 2018/5/29 大饼目前还是很耐扛的,跌入了第二个位置区间,但没有破掉,所以不着急找新位置。 6月7日前震荡上升。 吻合
102 2018/6/3 接下来就是看看btc能不能顺利站稳7800了,一旦稳住了,那么8700-9000几乎无悬念的成为了反弹的下一个目标位置。 未能站上7800。 吻合
103 2018/6/6 如果最后过不去7800,就会二次探底。 未能站上7800。 吻合
104 2018/6/14 下一波反弹目前为止应该都会到8700-9000。BTC的第三位置:5900-6100。 7月24日最高8488。 不吻合
105 2018/6/19 现在BTC上面有两个关键位置,一个是6900,一个是7800老位置。 未能突破。 吻合
106 2018/6/27 5900下面位置多,而且越跌入场的大资金和机构会越多。 确实。 吻合
107 2018/7/7 第一个位置就是6900,此位置过了以后,下一个压力位置就是7800, 再之后就有希望达到5月给的中期反弹目标8700-9000。 7月24日最高8488。 吻合
108 2018/7/14 只要能保持在6000附近,那么就会有第二次冲击的机会的。 7月24日最高8488。 吻合
109 2018/7/18 接下来一个压力位置是7800附近。 7月24日最高8488。 吻合
110 2018/7/25 现在上方就剩下8700这个中期最后一个位置了,暂时不给新位置,因为8700-9000必回调。 当日最高8482。 吻合
111 2018/8/2 比特币当下是和第一支撑位置在作斗争,也就是7500-7550附近,这个位置守不住,直接去往7000以下。 8月14日最低5900。 吻合
112 2018/8/8 这里是不是底现在言之过早,但是按照现在这个跌法持续下去的话,破6000那是大概率的事情了,后面跌到6000-6200我们再分析之后的情况。 当日最低6121。 大致吻合
113 2018/8/11 这个位置这一轮大概率是要破掉的,一旦6000-6200彻底破了,那么就得回到5300附近了。到时候离建仓期就近了。 没有破掉。 不吻合
114 2018/8/15 可以陆续进场建仓了,说明在此筑底了。 9月4日最高7402。 吻合
115 2018/8/25 现在上方面临的第一个位置就是6800附近了,上一波虽然冲到了6900,但那一轮显然是不正常,一旦再次稳过这个位置,那么这一轮摸8000的屁股就是大概率了。 9月4日最高7402。 大致吻合
116 2018/8/29 这一波上涨完了,应该会有第二波上涨,第二波上涨就是直接攻8000了,至于会不会有更高的位置现在而言是没有的。 9月4日最高7402。 大致吻合
117 2018/9/4 8000仍然是这一波顶,暂时没有更高位置。 当日最高7402。 大致吻合
118 2018/9/6 文章被建议修改:违反知乎社区管理规定。 - -
119 2018/9/16 好的一面是这一波连6000都没有跌破,所以目前向上反弹的概率更大了。不好地方在于跌涨幅度这么小,这一波反弹的位置也不会很高,就是利润不会很大。 11月14日跌破6000。 大致吻合
120 2018/9/25 这几天就在6600附近波动。 11月14日跌破6000。 吻合
121 2018/10/2 之前6600也是花了一段日子才过去,现在6900看样子也是。这个位置过了就可以直接到上一波的最高点7400附近瞅瞅了。 11月14日跌破6000。 吻合
122 2018/10/13 现在下有5900上有6900,上去和下去都需要量才有希望。 11月14日跌破6000。 吻合
123 2018/10/18 不涨就继续拿着等涨,涨了才考虑出,只要不大跌,小跌会继续补。 11月14日跌破6000。 吻合
124 2018/10/23 只要跌就能买,而这也是定投的机会,投资要往远了看。 11月14日跌破6000。 吻合
125 2018/10/29 比特币继续筑底,继续给了所有人逐步建仓的机会,给了所有人熊市埋伏定投,等待下一轮牛市投资翻几番的机会,回报不是一天,不是一个月,可能需要几年。放长线钓大鱼。 11月14日跌破6000。 吻合
126 2018/11/14 继续定投,继续跌就买。 当日跌破6000。 吻合
127 2018/12/17 比特币破了5600-5800这个重要关口以后就一路向下了,3600这个关口最后也破了,3000就是个心理位置也不是什么有力的支撑, 不能有效回到3600最后就得去往2200左右了,然后就是1000左右了. 那真的就是从哪儿来的回哪儿去了。 12月15日最低3128。 吻合
128 2019/2/18 这一波到底是筑底还是荡一荡继续跌,还是要等待接下来1个月左右的走势再做判断。 开涨。 吻合
129 2019/2/26 回落停留在3600附近就止跌的话,将极大的增加结束熊市的概率,同时我们可以现货入场开始长期持有,等待未来几个月到几年的一步步突破。回调如果停留在3200-3600我们就要谨慎了对待了,会增加继续熊市的概率,如果破了3200那就是继续熊市了,没什么好说的了,等新低。 开涨。 吻合
130 2019/3/15 现在比特币维持在了36xx-38xx之间,在熊市结束的前提下,这个位置会慢慢过的,应该不用担心。 持续上涨。 吻合
131 2019/3/23 比特币上方面临的第一大阻力位置就是4200了,过了这个位置会在5300附近遇到下一个强有力的阻力。 持续上涨。 吻合
132 2019/4/2 一旦冲击过了4200,接下来将会有持续的慢涨行情。 持续上涨。 吻合
133 2019/4/4 正常来说这一波想继续冲过5300直接去往下一个位置6000+可能性不大,因为需要很大的资金量和散户才能达成, 所以应该离回调越来越近了。 没有明显回调。 不吻合
134 2019/4/8 所以正常来说后期回落保持在4200之上,然后下一步继续冲击6000都是健康走势。 持续上涨。 吻合
135 2019/4/12 比特币回落的第一个位置应该在4600-4800。 当日最低价格为4901。 不吻合
136 2019/4/23 目前为止比特币没有有效的回调,这个位置很难连续冲起来,毕竟不是牛市。 持续上涨。 不吻合
137 2019/4/29 就目前来看,我仍然觉得比特币回到4800-4600是比较让我踏实的地方。如果不能回到这个位置, 那么如果能在5000以上继续震荡3-4个星期以上,我也会觉得很踏实,也会觉得回调结束,可以重新入场等下一波涨了。 持续上涨。 吻合
138 2019/5/4 后面的上涨空间是有限的。首先就是5900这个位置,然后是6400-6500. 我是觉得极限位置也就差不多是这里了。 持续上涨。 不吻合
139 2019/5/12 技术上来说目前都摸了7200了,所以会继续尝试摸7500.继续往上那就是8600了。 持续上涨。 吻合
140 2019/5/18 但凡能在6900-7100震荡几周那都是好事。不论最后是在7000附近震荡时间换取空间还是回去5800-6000,都不会重回熊市,相反是给了错过上一波的人一个机会。 持续上涨。 吻合
141 2019/5/28 以后任何级别的回调都是买入上车的机会。 持续上涨。 吻合
142 2019/6/11 后市可期,现在仅仅是小小牛而已。 持续上涨。 吻合
143 2019/6/18 破万以后必然是小牛市,回调那是给踏空者的机会,回调那是为了日后尽快重新到2万。 6月26日达到最高13868。 吻合
144 2019/6/22 比特币近期应该会继续尝试突破1万2。 6月26日达到最高13868。 吻合
145 2019/6/26 冲击1万2结束以后,再来一次2000多点的回落,再加上一段日子的震荡,那么后期的目标位置只会越来越高,重回历史最高2万就近在咫尺了。 7月10日达到最高13202。 吻合
146 2019/6/28 今天必然会有一波拉升,再拉到1万2以上也很轻松,但短期内必定还要再次跌1000-2000点。 非常吻合。 吻合
147 2019/7/4 现在需要注意的是30号从10300反弹的高点12900,把这个位置冲过了,代表这是要冲击这一波的新高13800了,而如果把前前高13800也过了,那继续大涨呗。 未能突破后回调。 吻合
148 2019/7/12 现在反弹着重关注的是13100和13900了。只有两个都过了才能把这个短期走势扭转过来继续大涨。 回调阶段。 吻合
149 2019/7/17 就算9600失守了收不回来了,那么最多最多再来一波8000附近也就完事了。 吻合。 吻合
150 2019/7/26 应该离回调结束只剩下最后一波了。 吻合。 吻合

Unable to load dynamic library 'intl'.

前一段时间重装了系统,执行composer install的时候发现报错如下图所示:

报错

Google了一下发现只有一位日本友人和我有一样的困扰: Bug #77690 Unable to load dynamic library intl.

再次执行php -v发现需要安装Visual C++ 2017:

详细信息

前往官网下载安装即可。


NOJ2019个人专题赛第一场题解

A - CF651B Beautiful Paintings

1000ms 262144K

Description:

There are $n$ pictures delivered for the new exhibition. The $i$-th painting has beauty $a_i$. We know that a visitor becomes happy every time he passes from a painting to a more beautiful one.

We are allowed to arranged pictures in any order. What is the maximum possible number of times the visitor may become happy while passing all pictures from first to last? In other words, we are allowed to rearrange elements of $a$ in any order. What is the maximum possible number of indices $i$ (1 ≤ $i$ ≤ $n$ - 1), such that $a_{i+1}$ > $a_i$.

Input:

The first line of the input contains integer $n$ (1 ≤ $n$ ≤ 1000) — the number of painting.

The second line contains the sequence $a_1$, $a_2$, ..., $a_n$ (1 ≤ $a_i$ ≤ 1000), where $a_i$ means the beauty of the $i$-th painting.

Output:

Print one integer — the maximum possible number of neighbouring pairs, such that $a_{i+1}$ > $a_i$, after the optimal rearrangement.

Sample Input:

520 30 10 50 40

Sample Output:

4

Sample Input:

4200 100 100 200

Sample Output:

2

Note:

In the first sample, the optimal order is: 10, 20, 30, 40, 50.

In the second sample, the optimal order is: 100, 200, 100, 200.

分析:

题目大意是说将一个数组排序,使得$a_{i+1}$ > $a_i$的次数最多。

规律是用总长度减去出现单一值的最多出现次数。

题解:

#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
int a[1005];
int main(void) {
    int n;
    scanf("%d", &n);
    for(int i=0;i<n;i++) {
        int x;
        scanf("%d", &x);
        a[x]++;
    }
    printf("%d\n", n - *max_element(a, a+1001));
    return 0;
}

B - CF758A Holiday Of Equality

1000ms 262144K

Description:

In Berland it is the holiday of equality. In honor of the holiday the king decided to equalize the welfare of all citizens in Berland by the expense of the state treasury.

Totally in Berland there are $n$ citizens, the welfare of each of them is estimated as the integer in $a_i$ burles (burle is the currency in Berland).

You are the royal treasurer, which needs to count the minimum charges of the kingdom on the king's present. The king can only give money, he hasn't a power to take away them.

Input:

The first line contains the integer $n$ (1 ≤ $n$ ≤ 100) — the number of citizens in the kingdom.

The second line contains $n$ integers $a_1$, $a_2$, ..., $a_n$, where $a_i$ (0 ≤ $a_i$ ≤ 106) — the welfare of the $i$-th citizen.

Output:

In the only line print the integer $S$ — the minimum number of burles which are had to spend.

Sample Input:

50 1 2 3 4

Sample Output:

10

Sample Input:

51 1 0 1 1

Sample Output:

1

Sample Input:

31 3 1

Sample Output:

4

Sample Input:

112

Sample Output:

0

Note:

In the first example if we add to the first citizen 4 burles, to the second 3, to the third 2 and to the fourth 1, then the welfare of all citizens will equal 4.

In the second example it is enough to give one burle to the third citizen.

In the third example it is necessary to give two burles to the first and the third citizens to make the welfare of citizens equal 3.

In the fourth example it is possible to give nothing to everyone because all citizens have 12 burles.

分析:

给定一个数组,通过扩大某些数的大小使得数组每个数都相等。

只需求出最大值,减去每个数然后求和即可。

题解:

#include<iostream>
using namespace std;
int m,s,n,a;
int main()
{
    cin>>n;
    for(int x=1;x<=n;x++)cin>>a,m=max(m,a),s+=a;
    cout<<n*m-s;
    return 0;
}

C - CF935A Fafa and his Company

1000ms 262144K

Description:

Fafa owns a company that works on huge projects. There are $n$ employees in Fafa's company. Whenever the company has a new project to start working on, Fafa has to divide the tasks of this project among all the employees.

Fafa finds doing this every time is very tiring for him. So, he decided to choose the best $l$ employees in his company as team leaders. Whenever there is a new project, Fafa will divide the tasks among only the team leaders and each team leader will be responsible of some positive number of employees to give them the tasks. To make this process fair for the team leaders, each one of them should be responsible for the same number of employees. Moreover, every employee, who is not a team leader, has to be under the responsibility of exactly one team leader, and no team leader is responsible for another team leader.

Given the number of employees $n$, find in how many ways Fafa could choose the number of team leaders $l$ in such a way that it is possible to divide employees between them evenly.

Input:

The input consists of a single line containing a positive integer $n$ (2 ≤ $n$ ≤ 105) — the number of employees in Fafa's company.

Output:

Print a single integer representing the answer to the problem.

Sample Input:

2

Sample Output:

1

Sample Input:

10

Sample Output:

3

Note:

In the second sample Fafa has 3 ways:

  • choose only 1 employee as a team leader with 9 employees under his responsibility.
  • choose 2 employees as team leaders with 4 employees under the responsibility of each of them.
  • choose 5 employees as team leaders with 1 employee under the responsibility of each of them.

分析:

暴力判断总员工数能不能被老大数整除即可。

题解:

#include<cstdio>
using namespace std;
int main(){
    int n,ans=0;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        if(n%i==0) ans++;
    }
    printf("%d",ans);
    return 0;
}

D - POJ1835 宇航员

2000ms 30000K

Description:

问题描述:

  宇航员在太空中迷失了方向,在他的起始位置现在建立一个虚拟xyz坐标系,称为绝对坐标系,宇航员正面的方向为x轴正方向,头顶方向为z轴正方向,则宇航员的初始状态如下图所示:

img

现对六个方向分别标号,x,y,z正方向分别为0,1,2,负方向分别为3,4,5;称它们为绝对方向。宇航员在宇宙中只沿着与绝对坐标系xyz轴平行的方向行走,但是他不知道自己当前绝对坐标和自己面向的绝对方向。

任务描述:

  请根据宇航员对自己在相对方向上移动的描述确定宇航员最终的绝对坐标和面向的绝对方向。对在相对方向上移动的描述及意义如下:

forward x  向前走x米。

back x 先转向后,再走x米。

left x 先转向左,再走x米。

right x 先转向右,再走x米。

up x 先面向上,再走x米。

down x 先面向下,再走x米。

其中向上和向下如下图所示:

img

Input:

第一行一个正整数m,表示测试数据的组数。每组测试数据第一行是一个正整数n(1<=n<=10000)表示宇航员行走的次数,下面n行每行输入一次相对行走,格式如上所述,其中( 1 <= x <= 10000 为正整数)。

Output:

对于每组输入数据输出一行,x y z p, 中间用空格隔开,x y z是宇航员的位置的绝对坐标,p是宇航员面向的绝对方向编号(0<=p <=5)。

Sample Input:

1
6
left 10
right 11
up 12
down 13
forward 14
back 15

Sample Output:

23 -10 12 3

分析:

这一题出的还是蛮巧妙的。训练的时候估算了一下,大概是几百行的代码量,就没有动手去写。

实际上只需要二十几行就可以完成,先确定宇航员的方向,然后再确定宇航员走的步数即可。

题解:

#include<cstdio>
char s[10];
int main(){
    int t, n;
    int x, y, z, face, left, head, temp, move;
    scanf("%d", &t);
    while (t--){
        scanf("%d", &n);
        x = y = z = 0;
        face = 0, left = 4, head = 2;
        while (n--){
            scanf("%s %d", s, &move);
            if (s[0] == 'b')  face = (face + 3) % 6, left = (left + 3) % 6;
            else if (s[0] == 'l')  temp = face, face = left, left = (temp + 3) % 6;
            else if (s[0] == 'r')  temp = left, left = face, face = (temp + 3) % 6;
            else if (s[0] == 'u')  temp = face, face = head, head = (temp + 3) % 6;
            else if (s[0] == 'd')  temp = head, head = face, face = (temp + 3) % 6;
            if (face == 0)  x += move;
            else if (face == 1)  y += move;
            else if (face == 2)  z += move;
            else if (face == 3)  x -= move;
            else if (face == 4)  y -= move;
            else  z -= move;
        }
        printf("%d %d %d %d\n", x, y, z, face);
    }
    return 0;
}

E - CF1060A Phone Numbers

2000ms 524288K

Description:

Let's call a string a phone number if it has length 11 and fits the pattern "8xxxxxxxxxx", where each "x" is replaced by a digit.

For example, "80123456789" and "80000000000" are phone numbers, while "8012345678" and "79000000000" are not.

You have nn cards with digits, and you want to use them to make as many phone numbers as possible. Each card must be used in at most one phone number, and you don't have to use all cards. The phone numbers do not necessarily have to be distinct.

Input:

The first line contains an integer nn — the number of cards with digits that you have (1≤n≤1001≤n≤100).

The second line contains a string of nn digits (characters "0", "1", ..., "9") s1,s2,…,sns1,s2,…,sn. The string will not contain any other characters, such as leading or trailing spaces.

Output:

If at least one phone number can be made from these cards, output the maximum number of phone numbers that can be made. Otherwise, output 0.

Sample Input:

1100000000008

Sample Output:

1

Sample Input:

220011223344556677889988

Sample Output:

2

Sample Input:

1131415926535

Sample Output:

0

Note:

In the first example, one phone number, "8000000000", can be made from these cards.

In the second example, you can make two phone numbers from the cards, for example, "80123456789" and "80123456789".

In the third example you can't make any phone number from the given cards.

分析:

给定一些数字,问最多能生成多少个电话号码。电话号码要满足以8开头、11位数两个特征。

只需要输出8的个数和总数字数量除以11中小的那个即可。

题解:

#include<cstdio>
#include<iostream>
using namespace std;
int main(){
    int count=0;
    int t;
    char temp;
    cin >> t;
    for(int i = 0; i < t; i++){
        cin >> temp;
        if(temp=='8'){
            count++;
        }
    }
    int tmp = t / 11;
    if(tmp > count){
        printf("%d", count);
    }else{
        printf("%d", tmp);
    }
    return 0;
}

F - CF1057B DDoS

2000ms 262144K

Description:

We get more and more news about DDoS-attacks of popular websites.

Arseny is an admin and he thinks that a website is under a DDoS-attack if the total number of requests for a some period of time exceeds 100⋅t100⋅t, where tt — the number of seconds in this time segment.

Arseny knows statistics on the number of requests per second since the server is booted. He knows the sequence r1,r2,…,rnr1,r2,…,rn, where riri — the number of requests in the ii-th second after boot.

Determine the length of the longest continuous period of time, which Arseny considers to be a DDoS-attack. A seeking time period should not go beyond the boundaries of the segment [1,n][1,n].

Input:

The first line contains nn (1≤n≤50001≤n≤5000) — number of seconds since server has been booted. The second line contains sequence of integers r1,r2,…,rnr1,r2,…,rn (0≤ri≤50000≤ri≤5000), riri — number of requests in the ii-th second.

Output:

Print the only integer number — the length of the longest time period which is considered to be a DDoS-attack by Arseny. If it doesn't exist print 0.

Sample Input:

5100 200 1 1 1

Sample Output:

3

Sample Input:

51 2 3 4 5

Sample Output:

0

Sample Input:

2101 99

Sample Output:

1

分析:

考的是前缀和。

题解:

#include<iostream>
using namespace std;
int n,maxnn=0,maxmm=0;
int a[5050],s[5050];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        int t;cin>>t;
        a[i]=t;
        s[i]=s[i-1]+t;
    }
    for(int i=n;i>=1;i--){
        for(int j=0;j<i;j++){
            if((s[i]-s[j])>(100*(i-j))&&i-j>maxnn){
                maxnn=i-j;
                break;
            }
        }
    }
    cout<<maxnn<<endl;
    return 0;
}

G - CF908A New Year and Counting Cards

1000ms 262144K

Description:

Your friend has $n$ cards.

You know that each card has a lowercase English letter on one side and a digit on the other.

Currently, your friend has laid out the cards on a table so only one side of each card is visible.

You would like to know if the following statement is true for cards that your friend owns: "If a card has a vowel on one side, then it has an even digit on the other side." More specifically, a vowel is one of 'a', 'e', 'i', 'o' or 'u', and even digit is one of '0', '2', '4', '6' or '8'.

For example, if a card has 'a' on one side, and '6' on the other side, then this statement is true for it. Also, the statement is true, for example, for a card with 'b' and '4', and for a card with 'b' and '3' (since the letter is not a vowel). The statement is false, for example, for card with 'e' and '5'. You are interested if the statement is true for all cards. In particular, if no card has a vowel, the statement is true.

To determine this, you can flip over some cards to reveal the other side. You would like to know what is the minimum number of cards you need to flip in the worst case in order to verify that the statement is true.

Input:

The first and only line of input will contain a string $s$ (1 ≤ |$s$| ≤ 50), denoting the sides of the cards that you can see on the table currently. Each character of $s$ is either a lowercase English letter or a digit.

Output:

Print a single integer, the minimum number of cards you must turn over to verify your claim.

Sample Input:

ee

Sample Output:

2

Sample Input:

z

Sample Output:

0

Sample Input:

0ay1

Sample Output:

2

Note:

In the first sample, we must turn over both cards. Note that even though both cards have the same letter, they could possibly have different numbers on the other side.

In the second sample, we don't need to turn over any cards. The statement is vacuously true, since you know your friend has no cards with a vowel on them.

In the third sample, we need to flip the second and fourth cards.

分析:

需要翻元音字母和奇数数字。

题解:

#include<cstdio>
#include<iostream>
using namespace std;
int main(){
    int count=0;
    char temp;
    while(true){
        scanf("%c", &temp);
        if(temp=='\n'){
            break;
        }
        if(temp == 'a' || temp == 'e' || temp == 'i' || temp == 'o' || temp == 'u' || temp == '1' || temp == '3' || temp == '5' || temp == '7' || temp == '9'){
            count++;
        }
    }
    printf("%d", count);
    return 0;
}

H - CF808A Lucky Year

1000ms 262144K

Description:

Apart from having lots of holidays throughout the year, residents of Berland also have whole lucky years. Year is considered lucky if it has no more than 1 non-zero digit in its number. So years 100, 40000, 5 are luckyand 12, 3001 and 12345 are not.

You are given current year in Berland. Your task is to find how long will residents of Berland wait till the next lucky year.

Input:

The first line contains integer number $n$ (1 ≤ $n$ ≤ 109) — current year in Berland.

Output:

Output amount of years from the current year to the next lucky one.

Sample Input:

4

Sample Output:

1

Sample Input:

201

Sample Output:

99

Sample Input:

4000

Sample Output:

1000

Note:

In the first example next lucky year is 5. In the second one — 300. In the third — 5000.

分析:

仅需把最高位的数+1取整再减原来的数即可。

比如2345的最高位数+1取整得3000,输出3000-2345即可。

不过这一题有一个大坑!不能用pow函数,要自己写一个。

题解:

#include<cstdio>
#include<iostream>
#include<cmath>

using namespace std;

long long poww(int count){
    if(count == 0) return 1;
    else return 10*poww(count-1);
}

int main(){
    long long year;
    int count = 0;
    cin >> year;
    long long backup = year;
    while(year > 9){
        year = year / 10;
        count++;
    }
    long long temp = (year + 1) * poww(count);
    cout << temp - backup;
    return 0;
}

I - CF954A Diagonal Walking

1000ms 262144K

Description:

Mikhail walks on a 2D plane. He can go either up or right. You are given a sequence of Mikhail's moves. He thinks that this sequence is too long and he wants to make it as short as possible.

In the given sequence moving up is described by character U and moving right is described by character R. Mikhail can replace any pair of consecutive moves RU or UR with a diagonal move (described as character D). After that, he can go on and do some other replacements, until there is no pair of consecutive moves RU or UR left.

Your problem is to print the minimum possible length of the sequence of moves after the replacements.

Input:

The first line of the input contains one integer $n$ (1 ≤ $n$ ≤ 100) — the length of the sequence. The second line contains the sequence consisting of $n$ characters U and R.

Output:

Print the minimum possible length of the sequence of moves after all replacements are done.

Sample Input:

5
RUURU

Sample Output:

3

Sample Input:

17
UUURRRRRUUURURUUU

Sample Output:

13

Note:

In the first test the shortened sequence of moves may be DUD (its length is 3).

In the second test the shortened sequence of moves can be UUDRRRDUDDUUU (its length is 13).

分析:

判断一下和上一步是不是不同,如果是就步数不变,如果不是就加一步。

题解:

#include<cstdio>
#include<iostream>
using namespace std;
char arr[105];
int main(){
    int t;
    int count=0;
    cin >> t;
    for(int i = 0; i < t; i++){
        cin >> arr[i];
        if(i != 0 && arr[i] != arr[i-1] && arr[i-1] != 'D'){
            arr[i] = 'D';
        }else{
            count++;
        }
    }
    printf("%d", count);
    return 0;
}

J - CF1006A Adjacent Replacements

1000ms 262144K

Description:

Mishka got an integer array aa of length nn as a birthday present (what a surprise!).

Mishka doesn't like this present and wants to change it somehow. He has invented an algorithm and called it "Mishka's Adjacent Replacements Algorithm". This algorithm can be represented as a sequence of steps:

  • Replace each occurrence of 11 in the array aa with 22;
  • Replace each occurrence of 22 in the array aa with 11;
  • Replace each occurrence of 33 in the array aa with 44;
  • Replace each occurrence of 44 in the array aa with 33;
  • Replace each occurrence of 55 in the array aa with 66;
  • Replace each occurrence of 66 in the array aa with 55;
  • ……
  • Replace each occurrence of 109−1109−1 in the array aa with 109109;
  • Replace each occurrence of 109109 in the array aa with 109−1109−1.

Note that the dots in the middle of this algorithm mean that Mishka applies these replacements for each pair of adjacent integers (2i−1,2i2i−1,2i) for each i∈{1,2,…,5⋅108}i∈{1,2,…,5⋅108} as described above.

For example, for the array a=[1,2,4,5,10]a=[1,2,4,5,10], the following sequence of arrays represents the algorithm:

[1,2,4,5,10][1,2,4,5,10] →→ (replace all occurrences of 11 with 22) →→ [2,2,4,5,10][2,2,4,5,10] →→(replace all occurrences of 22 with 11) →→ [1,1,4,5,10][1,1,4,5,10] →→ (replace all occurrences of 33 with 44) →→ [1,1,4,5,10][1,1,4,5,10] →→ (replace all occurrences of 44with 33) →→ [1,1,3,5,10][1,1,3,5,10] →→ (replace all occurrences of 55 with 66) →→ [1,1,3,6,10][1,1,3,6,10] →→ (replace all occurrences of 66 with 55) →→ [1,1,3,5,10][1,1,3,5,10] →→ ……→→ [1,1,3,5,10][1,1,3,5,10] →→ (replace all occurrences of 1010 with 99) →→ [1,1,3,5,9][1,1,3,5,9]. The later steps of the algorithm do not change the array.

Mishka is very lazy and he doesn't want to apply these changes by himself. But he is very interested in their result. Help him find it.

Input:

The first line of the input contains one integer number nn (1≤n≤10001≤n≤1000) — the number of elements in Mishka's birthday present (surprisingly, an array).

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the elements of the array.

Output:

Print nn integers — b1,b2,…,bnb1,b2,…,bn, where bibi is the final value of the ii-th element of the array after applying "Mishka's Adjacent Replacements Algorithm" to the array aa. Note that you cannot change the order of elements in the array.

Sample Input:

51 2 4 5 10

Sample Output:

1 1 3 5 9

Sample Input:

1010000 10 50605065 1 5 89 5 999999999 60506056 1000000000

Sample Output:

9999 9 50605065 1 5 89 5 999999999 60506055 999999999

Note:

The first example is described in the problem statement.

分析:

把所有的偶数减一。

题解:

#include<iostream>
using namespace std;
long long array[1005];
int main(){
    int t;
    cin >> t;
    for(int i = 0; i < t; i++){
        cin >> array[i];
    }
    for(int i = 0; i < t; i++){
        if(array[i] % 2){
            cout << array[i];
        }else{
            cout << array[i]-1;
        }
        if(i != t-1) cout << " ";
    }
    return 0;
}

数字货币交易指南

从2010年一万枚比特币换两个披萨的交易起,到如今交易所中的约1万美元换一枚比特币。比特币的价值在短短的十年间翻了约四百万倍。这一奇迹吸引了源源不断的投资者与投机者进入这个市场,也让许多中国大陆的群众跃跃欲试。但是出于某些原因,我们进行交易的过程也许不是那么顺畅,今天我就来带着大家聊聊这件事。

值得注意的是,本篇文章不构成任何投资建议。数字货币是风险极高的投资品,其风险甚至远高于股票。如果你不能很明确地了解加密货币的基本原理,对于各种货币的基本面不了解的话,我建议你还是远离这个市场。毕竟,带着太强的功利心进入一个一无所知的高风险投机市场,最后的结局往往家破人亡,血本无归。

作为中国大陆的民众,目前最简单的方式就是采取法币交易+币币交易的模式。

法币交易是指通过银行转账、支付宝转账、微信转账等方式,将法币人民币与主流数字货币进行兑换的交易方式。优点在于……它是法币!也是你法币兑换数字货币的唯一出入口。但是缺点也很明显,由于和你交易的人一般是认证商家,交易时价格往往不是很优,交易的量一般也有限制。通常交易在五万元以上才会拿到比较好的价格,而这个门槛对于想入门试试水的人来说还是有点高了。

而币币交易就是在各种数字货币之间进行兑换。这里就要提一下USDT了。USDT是一家叫Tether的交易所发行的稳定币,其承诺每发行1USDT就会储备1美元作为背书。其理论值是1USDT=1USD,但是由于种种原因这并不是绝对的,在面向中国人的交易所中有时候USDT比美元“贵”,有时候又“便宜”一些。以现在为例,1USD=6.88CNY,但是1USDT=6.97CNY。其价格波动的具体原因不是本文的重点。

币币交易的优点在于可以实时交易,挂单等等,交易的金额也是可以随便设定的,一些交易所还提供止盈止损等选项,是比较方便的交易方式。所以我推荐法币交易入场,币币交易发财,再法币交易退场。这是比较明智的选择。

讲完了交易模式,是时候推荐一波交易所了。币圈的朋友们应该会公认这个观点:只在三大交易所交易:币安、火币、OKEX。

这三大交易所都非常的棒,只有一些小区别,我将它们没讲到的点整理成一个表格(截至2019年7月17日),请自行选择:

币安 火币 OKEX
法币交易 不支持 支持USDT、BTC、ETH、EOS等8种 支持USDT、BTC、ETH、EOS等14种
杠杆交易 支持 支持 支持
合约交易 不支持 支持 支持

虽然币安不支持法币交易,但是可以在其它两个交易所购买数字货币后再转入币安。同样,虽然火币和OKEX都支持杠杆和合约交易,但是杠杆和合约的风险太高,尤其是OKEX的简直是可以用臭名昭著来形容。所以究竟选哪个交易所还是要结合自身实际,审慎判断。

最后是这三家交易所的官网和注册链接。

币安:官网 注册链接

火币:官网 注册链接

OKEX:官网 注册链接

投资有风险 交易需谨慎 祝你发大财


区块链,不应是一场豪赌

随着比特币的起起伏伏,区块链的概念也越来越为人所知。区块链技术虽和人工智能、大数据、物联网一样,都是21世纪得到飞速发展的计算机技术,但是由于区块链技术的高门槛性,大多数人并不明确了解区块链技术到底是什么。区块链等于比特币吗?区块链是个骗局,还是大有用处?这篇文章,我将用通俗易懂的语言带你剖析区块链的前世今生,以及未来的发展方向。

区块链,首先还是要从比特币谈起。时间要回到2008年,一个代号叫中本聪的人发布了比特币白皮书:《比特币:一种点对点的电子现金系统》(Bitcoin: A peer-to-peer electronic cash system)。在这个白皮书里,中本聪提出了这样一种构想:比特币的每一笔交易其实都可以用一个字符串表示,我们将每4000条交易记录打包成一个区块(block),在区块头部添加一个唯一的特征码(具体技术细节略,感兴趣的可以搜索哈希算法)。如果再有4000条交易记录,就再生成一个区块,同时头部特征码的生成过程要包含上一个区块的特征码。这样区块就会一个接着一个地串起来变成一条链(chain),称作区块链(block chain)。

所以说,区块链是从比特币中抽象出来的一个概念。但是,区块链并不完全等同于比特币,区块链离开了比特币也可以作为一项技术为人类服务。这就要谈谈区块链的三个发展阶段。

在第一个阶段,也就是区块链1.0时代,区块链的最广泛应用以金融为主。由于交易的数据简单明确,交易系统易于构建,基于区块链的各种数字货币是区块链应用的主力军。

在第二个阶段,区块链2.0时代,区块链应用的核心是智能合约。但坦率地说,这个智能合约既不”智能“,也不”合约“。我更倾向于叫它”可编程金融“。在区块链1.0这种单纯的交易功能下,区块链2.0发展出了”可编程“这一特性。我们可以通过在链上编程,使得除转账之外的其它信息也被区块链存储。最知名的智能合约叫做”以太坊“。目前依我来看,我们正处于区块链2.0时代。由于区块链3.0的条件太过严苛,尽管有许多人尝试着做出类似区块链3.0的应用,但都没有取得比较好的效果。

在区块链3.0时代,区块链的核心是”可编程社会“。区块链技术会渗透到我们生活的方方面面。在医疗方面,病历可以在区块链上存储;在教育方面,学历可以在区块链上存储;在工业方面,操作可以在区块链上存储等等。以教育为例,现在存储在学信网上的学历信息其实并不是绝对安全的。我们假定学信网有一个高危漏洞,那我就可以侵入然后修改自己的学籍。但是,如果学历信息存储在区块链上,那么学历的安全问题将被解决。

现如今,有许多”伪区块链3.0“的项目在疯狂捞钱。但是,区块链3.0应该摆脱区块链1.0和2.0的金融属性,脱离数字货币才能让区块链更好地发展。中国区块链专利数量第一的阿里巴巴就曾明确表示自己不会发币。区块链技术的理解门槛高是区块链骗局多的主要原因之一。区块链是一个非常优秀的技术,我也反对任何将区块链与比特币绑定在一起的说法。区块链未来会和AI一样在生活中普及,只是大家对区块链的误解太多,想要真正实现区块链3.0时代还有很长的一段路要走。


PHPstudy2019发布

惊闻PHPstudy发布了2019版本正式版,我下载体验之后,觉得比2018版本的进步真的不是一点半点!

上几张截图给你们感受下!

phpstudy1

phpstudy2

phpstudy3

phpstudy4

phpstudy5

phpstudy6

话说我还发现他们给它起了个名字叫小皮系统,访问xp.cn也会重定向到官网2333。


NOJ榜单重构小结

今年上半年,我接了NOJ的第一个真正意义上的锅——重构比赛榜单。

期末考试结束,我终于可以好好谈谈这个重构是怎么实现的了。

之前的比赛榜单是这样生成的:

先去执行一个类似SELECT * FROM submission WHERE cid = $cid的SQL查询,然后根据查询到的赛中提交记录实时算一个榜单出来。这样做有什么问题呢?显而易见,那就是太慢了。每一个查询榜单的请求都需要调用一遍contestRank函数,contestRank函数再去调用一遍contestRankCache函数。但问题就是这个contestRankCache其实并不是cache。它这个函数的作用其实是传入一个包含所有比赛提交的集合对象,然后返回一个榜单的二维数组。由于计算的过程过于复杂,所以当计算榜单的时候会侵占学校垃圾的比赛服务器高达50%的CPU性能,更不用说多人同时查看榜单的情况了。记得一次榜单对外开放的比赛中途突然传出xxxAK的消息,大家冲进去看榜单,直接把服务器挤炸了,害的比赛选手交题时Submission Error。

所以,重构这个臭名昭著的榜单的重任就落在了我的头上。重构的思路是这样的:基于Redis驱动的Cache,以cid(比赛id)为键,比赛开始时建立一个空二维数组,当有选手交题时,根据单条交题记录去更新这个数组,该数组在Cache中永久保存。

这样一来,更新榜单的事件驱动就由请求榜单转为选手提交,大大减轻了服务器压力,请求榜单时也可以做到理论上的“秒开”。

以下是核心代码:

public function updateContestRankTable($cid,$sub){
    $lock = Cache::lock("contestrank$cid",10);
    try{
        if($lock->get()){
            if(Cache::tags(['contest','rank'])->get($cid) != null){
                $chache = Cache::tags(['contest','data'])->get($cid);
                $ret = Cache::tags(['contest','rank'])->get($cid);
                if (time() > $chache['frozen_time'])
                    return;

                $id = 0;

                foreach($chache['problemSet'] as $key => $p){
                    if ($p['pid'] == $sub['pid']){
                        $chache['problemSet'][$key]['cpid'] = $key;
                        $id = $key;
                    }
                }

                $ret = $this->updateContestRankDetail($chache['contest_info'],$chache['problemSet'][$id],$cid,$sub['uid'],$ret);
                $ret = $this->sortContestRankTable($chache['contest_info'],$cid,$ret);

                Cache::tags(['contest', 'rank'])->put($cid, $ret);
            }
            else{
                $ret=[];
                $chache=[];
                $chache['contest_info']=DB::table("contest")->where("cid", $cid)->first();
                $chache['problemSet']=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
                    "cid"=>$cid
                ])->orderBy('ncode', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title")->get()->all();
                $chache['frozen_time']=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
                $chache['end_time']=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);

                Cache::tags(['contest', 'data'])->put($cid, $chache);

                if ($chache['contest_info']["registration"]) {
                    $submissionUsers=DB::table("contest_participant")->where([
                        "cid"=>$cid,
                        "audit"=>1
                    ])->select('uid')->get()->all();
                }else{
                    $submissionUsers=DB::table("submission")->where([
                        "cid"=>$cid
                    ])->where(
                        "submission_date",
                        "<",
                        $chache['frozen_time']
                    )->select('uid')->groupBy('uid')->get()->all();
                }
                foreach ($submissionUsers as $s) {
                    foreach ($chache['problemSet'] as $key => $p) {
                        $p['cpid'] = $key;
                        $ret = $this->updateContestRankDetail($chache['contest_info'],$p,$cid,$s['uid'],$ret);
                    }
                }
                $ret = $this->sortContestRankTable($chache['contest_info'],$cid,$ret);
                Cache::tags(['contest', 'rank'])->put($cid, $ret);
            }
        }
    }catch(LockTimeoutException $e){
        Log::warning("Contest Rank Lock Timed Out");
    }finally{
        optional($lock)->release();
    }
}

public function sortContestRankTable($contest_info,$cid,$ret){
    if ($contest_info["rule"]==1){
        usort($ret, function ($a, $b) {
            if ($a["score"]==$b["score"]) {
                if ($a["penalty"]==$b["penalty"]) {
                    return 0;
                } elseif (($a["penalty"]>$b["penalty"])) {
                    return 1;
                } else {
                    return -1;
                }
            } elseif ($a["score"]>$b["score"]) {
                return -1;
            } else {
                return 1;
            }
        });
    }else if ($contest_info["rule"]==2){
        usort($ret, function ($a, $b) {
            if ($a["score"]==$b["score"]) {
                if ($a["solved"]==$b["solved"]) {
                    return 0;
                } elseif (($a["solved"]<$b["solved"])) {
                    return 1;
                } else {
                    return -1;
                }
            } elseif ($a["score"]>$b["score"]) {
                return -1;
            } else {
                return 1;
            }
        });
    }
    return $ret;
}

public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret){
    $id = count($ret);
    foreach($ret as $key => $r){
        if($r['uid'] == $uid)
            $id = $key;
    }
    if ($contest_info["rule"]==1) {
        // ACM/ICPC Mode
            if($id == count($ret)){
                $prob_detail = [];
                $totPen = 0;
                $totScore = 0;
            }else{
                $prob_detail = $ret[$id]['problem_detail'];
                $totPen=$ret[$id]['penalty'];
                $totScore=$ret[$id]['score'];
            };

            $prob_stat=$this->contestProblemInfoACM($cid, $problem["pid"], $uid);

            $prob_detail[$problem['cpid']]=[
                "ncode"=>$problem["ncode"],
                "pid"=>$problem["pid"],
                "color"=>$prob_stat["color"],
                "wrong_doings"=>$prob_stat["wrong_doings"],
                "solved_time_parsed"=>$prob_stat["solved_time_parsed"]
            ];
            if ($prob_stat["solved"]) {
                $totPen+=$prob_stat["wrong_doings"] * 20;
                $totPen+=$prob_stat["solved_time"] / 60;
                $totScore+=$prob_stat["solved"];
            }

            $ret[$id]=[
                "uid" => $uid,
                "name" => DB::table("users")->where([
                    "id"=>$uid
                ])->first()["name"],
                "nick_name" => DB::table("group_member")->where([
                    "uid" => $uid,
                    "gid" => $contest_info["gid"]
                ])->where("role", ">", 0)->first()["nick_name"],
                "score" => $totScore,
                "penalty" => $totPen,
                "problem_detail" => $prob_detail
            ];
    } elseif ($contest_info["rule"]==2) {
        // OI Mode
        if($id == count($ret)){
            $prob_detail = [];
            $totPen = 0;
            $totScore = 0;
        }else{
            $prob_detail = $ret[$id]['problem_detail'];
            $totPen=$ret[$id]['penalty'];
            $totScore=$ret[$id]['score'];
        };

        $prob_stat=$this->contestProblemInfoOI($cid, $problem["pid"], $uid);
        $prob_detail[$problem['cpid']]=[
            "ncode"=>$problem["ncode"],
            "pid"=>$problem["pid"],
            "color"=>$prob_stat["color"],
            "score"=>$prob_stat["score"],
            "score_parsed"=>$prob_stat["score_parsed"]
        ];
        $totSolved+=$prob_stat["solved"];
        $totScore+=intval($prob_stat["score_parsed"]);

        $ret[$id]=[
            "uid" => $uid,
            "name" => DB::table("users")->where([
                "id"=> $uid
            ])->first()["name"],
            "nick_name" => DB::table("group_member")->where([
                "uid" => $uid,
                "gid" => $contest_info["gid"]
            ])->where("role", ">", 0)->first()["nick_name"],
            "score" => $totScore,
            "solved" => $totSolved,
            "problem_detail" => $prob_detail
        ];
    }
    return $ret;
}

唉,不提了,写Contest Admin Portal去了。


三角迷宫

这是“Wishare杯”南邮第十一届大学生程序设计竞赛网络赛的C题。

Description:

如图为一个三角迷宫,迷宫中的数字从1开始标号。现给出两个数字m、n,请求出从m到n的最短路径,输出路径长度。

注:如图所示,迷宫中的数字被网格线所分隔,我们规定,穿过一次网格线,路径长度加一,初始路径长度为0。

1555125122634

Input:

第一行,一个整数T(0≤T≤1e6)。

接下来T行,每行两个整数,m、n(1≤m,n≤1e9​​)。

Output:

输出T行,每行一个整数,表示结果。

Sample Input:

1
6 12

Sample Output:

3

可惜我太菜了,用简单的分类讨论完成了这道题。

该图可以转化成一个自顶向下的组织关系图, row表示上下移动的次数,col表示左右移动的次数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

long long getrow(long long num){
    long long sqrtnum = (long long)sqrt(num);
    for(long long i = 1;i <= sqrtnum+1;i++){
        if(num <= i*i){
            return i;
        }
    }
}

long long getdiffcol(long long m,long long n){
    long long diffrow = getrow(n) - getrow(m);
    long long diffcol;
    diffcol = fabs(n - (m + diffrow * getrow(m) * 2 + diffrow * (diffrow - 1)));
    if(diffcol >= diffrow){
        return diffcol;
    }else{
        if(getrow(m)%2 == m%2){
            diffcol += ((diffrow - diffcol - 1) / 2 + (diffrow - diffcol - 1) % 2) * 2;
        }else{
            diffcol += ((diffrow - diffcol) / 2 + (diffrow - diffcol) % 2) * 2;
        }
    }
    return diffcol;
}

int main(){
    long long t,m,n,diffrow,diffcol;
    scanf("%lld", &t);
    while(t--){
        scanf("%lld%lld",&m,&n);
        if(m > n){
            swap(m,n);
        }
        diffrow = getrow(n) - getrow(m);
        diffcol = getdiffcol(m,n); 
        printf("%lld\n",diffrow + diffcol);
    }
    return 0;
}