2016-C23-team2
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
||Run ID||Time||Size||Problem||Language||Result||
||656||4:34:28||6452||F||g++0x||OK||
||651||4:21:23||6935||F||g++0x||Wrong answer||
||647||4:19:50||6935||F||g++0x||Time-limit exceeded||
||645||4:19:17||6936||F||g++0x||Time-limit exceeded||
||643||4:17:36||6892||F||g++0x||Time-limit exceeded||
||638||4:08:33||6496||F||g++0x||Wrong answer||
||636||4:07:03||6433||F||g++0x||Time-limit exceeded||
||635||4:03:20||837||J||g++0x||OK||
||629||3:54:46||672||J||g++0x||Wrong answer||
||604||2:50:18||1843||H||g++0x||OK||
||595||2:36:16||3107||H||g++0x||Wrong answer||
||593||2:32:31||2937||H||g++0x||Wrong answer||
||587||2:10:41||698||B||g++0x||OK||
||585||2:03:07||1713||D||g++0x||OK||
||578||1:40:39||1764||D||g++0x||Wrong answer||
||569||1:12:57||1816||E||g++0x||OK||
||564||1:00:09||1814||E||g++0x||Wrong answer||
||562||0:57:30||1814||E||g++0x||Wrong answer||
||557||0:36:51||1224||A||g++0x||OK||
||556||0:33:30||1111||E||g++0x||Wrong answer||
||551||0:27:25||1042||E||g++0x||Wrong answer||
||545||0:18:55||1877||E||g++0x||Wrong answer||
== 流水账 ==
=== TsReaper ===
开场比较不好,starve学长觉得E是简单题急忙去敲了,结果因为算法和程序中的一些错误一直没有通过。A题我也比较犯傻想复杂了...开场'''A1y36''','''E6y72'''。starve学长搞E的时候我和hzf学长弄清楚了D和H的做法,但是这两题都比较模拟(昨天北京网络赛也是很多模拟,感觉整个人都不太好...),'''D2y123''','''H3y170'''。我写D的过程中学长们会了B,'''B1y130'''。
比较可做的题貌似都做完了,我和hzf学长考虑C和J,starve学长尝试几何题F。一开始都没有什么思路,后来J我想到了分类讨论的方法,'''J2y243'''。starve学长的几何题+搜索也经过各种差错之后过了,'''F7y274''',这场脸还是比较白的...
== 总结 ==
=== TsReaper ===
* 做得好的地方
* 通过讨论把不平等博弈变成平等博弈的思路是非常正确的,NP问题用搜索解决的思路也是正确的。
* 做得不好的地方
* 代码能力还是有待加强,虽然有比较多的模拟题但是正确率还应该高一点。
== 题解 ==
AE比较容易,H虽然细节多但也容易,略过...
=== C - Decoding Ancient Messages ===
其实就是最大费用流,只不过费用是一个字典序,定义一个struct就好了...大家因为没有见过这种奇怪费用的费用流都没有敢写...
edit: 好吧...的确有一定困难...写的时候有一个小技巧,就是为了不让字典序里某个字母出现次数为负,我们可以在费用流的运算过程中,把上一次算出来的答案做为下一次的初始费用,这样就不会有负数了。
edit2: 转换成最大费用流就方便很多了(比如把费用视为一个50进制的数,这样多选一个字典序小的肯定优),负数问题就不怎么需要考虑了。
=== D - LR ===
显然是区间dp,不过最后答案可能略大,要自己写一个struct来记。
记s[i]表示第i个字符,一个合法区间[i,j]只有两种可能:
1. 这个区间是一个数,那么s[i]只能是1~9或?,s[i+1]~s[j]只能是0~9或?。确定这个区间可以是数后,我们就把所有?都变成9,就能得到最大的数。
2. 这个区间是一个函数,那么s[i]只能是L,R或?,s[i+1]只能是(或?,s[j]只能是)或?。确定这个区间可以是函数后,我们枚举逗号的位置(从i+3~j-2)。记lmax表示逗号左右两边都合法时,左边的最大值,rmax表示右边的最大值。则s[i]为L时,答案就是lmax;为R时,答案就是rmax;为?时,答案是max(lmax,rmax)。
=== F - Polygon Guards ===
经过几何的预处理后,问题变成了一般图的最小支配集。把点按能支配的点数排序,搜索一下即可。
=== J - Unfair Game ===
记M = min(A,B),如果A = B或每一堆石头个数都小等于M,那么这个问题就是一个公平游戏。若一堆石子有x个,很容易得到它的sg函数值为x mod (M+1).
现在我们讨论不公平游戏的情况(也就是A != B,且至少有一堆石头个数大于M),以下提到的sg值都是公平游戏下算出来的sg值。
如果A > B,且初始局面的sg值非0,显然先手必胜(直接把游戏当公平游戏玩即可,不使用一次拿取多于B个石头的操作)。
如果A > B,且初始局面为sg值为0,那么若先手能够通过一次操作,让操作后的局面sg值还是0,那么先手仍然必胜。这是可以做到的。因为至少有一堆石头个数大于M,而sg值的计算公式为x mod (M+1),那么先手只要从个数大于M的石头堆中拿走M+1个石头就可以了。所以先手仍然必胜。
如果A < B,且初始局面sg值为0,显然后手必胜。
如果A < B,且初始局面sg值非0,那么先手必胜的唯一机会,就是通过一次操作,让操作后的局面sg值为0,而且操作后的局面每一堆石头个数都小等于M。这样,后手就不能通过一次操作,让操作后的局面sg值还是0,从而获胜了。先手要拿走的石头个数x,我们可以通过sg值算出来。也就是说,如果初始局面只有一堆石头个数大于M,而且这堆石头拿走x个之后,个数小等于M,那么先手必胜,否则后手必胜。
== 补题 ==
=== TsReaper ===
~~C~~
| Run ID | Time | Size | Problem | Language | Result |
| 656 | 4:34:28 | 6452 | F | g++0x | OK |
| 651 | 4:21:23 | 6935 | F | g++0x | Wrong answer |
| 647 | 4:19:50 | 6935 | F | g++0x | Time-limit exceeded |
| 645 | 4:19:17 | 6936 | F | g++0x | Time-limit exceeded |
| 643 | 4:17:36 | 6892 | F | g++0x | Time-limit exceeded |
| 638 | 4:08:33 | 6496 | F | g++0x | Wrong answer |
| 636 | 4:07:03 | 6433 | F | g++0x | Time-limit exceeded |
| 635 | 4:03:20 | 837 | J | g++0x | OK |
| 629 | 3:54:46 | 672 | J | g++0x | Wrong answer |
| 604 | 2:50:18 | 1843 | H | g++0x | OK |
| 595 | 2:36:16 | 3107 | H | g++0x | Wrong answer |
| 593 | 2:32:31 | 2937 | H | g++0x | Wrong answer |
| 587 | 2:10:41 | 698 | B | g++0x | OK |
| 585 | 2:03:07 | 1713 | D | g++0x | OK |
| 578 | 1:40:39 | 1764 | D | g++0x | Wrong answer |
| 569 | 1:12:57 | 1816 | E | g++0x | OK |
| 564 | 1:00:09 | 1814 | E | g++0x | Wrong answer |
| 562 | 0:57:30 | 1814 | E | g++0x | Wrong answer |
| 557 | 0:36:51 | 1224 | A | g++0x | OK |
| 556 | 0:33:30 | 1111 | E | g++0x | Wrong answer |
| 551 | 0:27:25 | 1042 | E | g++0x | Wrong answer |
| 545 | 0:18:55 | 1877 | E | g++0x | Wrong answer |
流水账
TsReaper
开场比较不好,starve学长觉得E是简单题急忙去敲了,结果因为算法和程序中的一些错误一直没有通过。A题我也比较犯傻想复杂了...开场A1y36,E6y72。starve学长搞E的时候我和hzf学长弄清楚了D和H的做法,但是这两题都比较模拟(昨天北京网络赛也是很多模拟,感觉整个人都不太好...),D2y123,H3y170。我写D的过程中学长们会了B,B1y130。
比较可做的题貌似都做完了,我和hzf学长考虑C和J,starve学长尝试几何题F。一开始都没有什么思路,后来J我想到了分类讨论的方法,J2y243。starve学长的几何题+搜索也经过各种差错之后过了,F7y274,这场脸还是比较白的...
总结
TsReaper
- 做得好的地方
- 通过讨论把不平等博弈变成平等博弈的思路是非常正确的,NP问题用搜索解决的思路也是正确的。
- 做得不好的地方
- 代码能力还是有待加强,虽然有比较多的模拟题但是正确率还应该高一点。
题解
AE比较容易,H虽然细节多但也容易,略过...
C - Decoding Ancient Messages
其实就是最大费用流,只不过费用是一个字典序,定义一个struct就好了...大家因为没有见过这种奇怪费用的费用流都没有敢写...
edit: 好吧...的确有一定困难...写的时候有一个小技巧,就是为了不让字典序里某个字母出现次数为负,我们可以在费用流的运算过程中,把上一次算出来的答案做为下一次的初始费用,这样就不会有负数了。
edit2: 转换成最大费用流就方便很多了(比如把费用视为一个50进制的数,这样多选一个字典序小的肯定优),负数问题就不怎么需要考虑了。
D - LR
显然是区间dp,不过最后答案可能略大,要自己写一个struct来记。
记s[i]表示第i个字符,一个合法区间[i,j]只有两种可能:
1. 这个区间是一个数,那么s[i]只能是1~9或?,s[i+1]~s[j]只能是0~9或?。确定这个区间可以是数后,我们就把所有?都变成9,就能得到最大的数。
2. 这个区间是一个函数,那么s[i]只能是L,R或?,s[i+1]只能是(或?,s[j]只能是)或?。确定这个区间可以是函数后,我们枚举逗号的位置(从i+3~j-2)。记lmax表示逗号左右两边都合法时,左边的最大值,rmax表示右边的最大值。则s[i]为L时,答案就是lmax;为R时,答案就是rmax;为?时,答案是max(lmax,rmax)。
F - Polygon Guards
经过几何的预处理后,问题变成了一般图的最小支配集。把点按能支配的点数排序,搜索一下即可。
J - Unfair Game
记M = min(A,B),如果A = B或每一堆石头个数都小等于M,那么这个问题就是一个公平游戏。若一堆石子有x个,很容易得到它的sg函数值为x mod (M+1).
现在我们讨论不公平游戏的情况(也就是A != B,且至少有一堆石头个数大于M),以下提到的sg值都是公平游戏下算出来的sg值。
如果A > B,且初始局面的sg值非0,显然先手必胜(直接把游戏当公平游戏玩即可,不使用一次拿取多于B个石头的操作)。
如果A > B,且初始局面为sg值为0,那么若先手能够通过一次操作,让操作后的局面sg值还是0,那么先手仍然必胜。这是可以做到的。因为至少有一堆石头个数大于M,而sg值的计算公式为x mod (M+1),那么先手只要从个数大于M的石头堆中拿走M+1个石头就可以了。所以先手仍然必胜。
如果A < B,且初始局面sg值为0,显然后手必胜。
如果A < B,且初始局面sg值非0,那么先手必胜的唯一机会,就是通过一次操作,让操作后的局面sg值为0,而且操作后的局面每一堆石头个数都小等于M。这样,后手就不能通过一次操作,让操作后的局面sg值还是0,从而获胜了。先手要拿走的石头个数x,我们可以通过sg值算出来。也就是说,如果初始局面只有一堆石头个数大于M,而且这堆石头拿走x个之后,个数小等于M,那么先手必胜,否则后手必胜。
补题
TsReaper
C
附加文件
- 2016-C23-team2.zip by TsReaper
- C.cpp by TsReaper
- C2.cpp by TsReaper