
ACM题解
文章平均质量分 68
Dinosoft
囧轩,男。 小学参加数学奥赛,拿了一些奖; 初中买了书自学c语言和photoshop,玩过flash, dreamweaver,3D max 等东东; 高中自学Pascal,参加NOIP,开始接触数据结构 算法,没拿什么奖,要准备高考,伤不起; 大学参加acm,拿了点奖。业余做做网站,弹弹吉他,现在下岗待业。 -----一个苦B的IT民工走过的路。
展开
-
HDU 1074 Doing Homework
<br />动态规划,先算只做一个homework的罚分,接着算2个、3个。。网上找来找去只有一份代码,被copy来copy去,所以我把自己的代码贴上来。<br /><br />这个是HDU的acm课件里面的截图。有点像数塔。不过状态不好保存。<br /> <br /> <br />//46MS 1112K 1791B G++ //使用状态压缩,如01001(二进制)表示做了第一个和第四个作业。#include <stdio.h>#include <string.h>struct dp_原创 2010-06-18 00:20:00 · 2239 阅读 · 0 评论 -
1048 Inverso
<br />TAG 宽度优先搜索<br /> <br />明确几点:<br />1.每个操作最多出现一次。因为重复操作会抵消。<br />2.操作的次序对最后结果没有影响。<br />3.从初始状态变换到全白,跟从全白变换到初始状态的操作步骤是一致的。<br /> <br />所以<br />1.不必每次都搜索一次,预处理一次后,后面可以直接输出结果。<br />2.使操作步骤序号递增,且每个序号最多输出一次。<br />3.使用宽度优先搜索可以保证最后操作次数最少。<br /> <br />输入全白时要输原创 2010-08-28 17:10:00 · 1986 阅读 · 0 评论 -
1206. Stacking Cylinders & 1012. Stacking Cylinders
<br />TAG 简单几何计算<br /> <br />这两道题题目是一样的,不过输出格式有点不同,而且1206的Sample input故意设下陷阱:让人误以为输入数据有序。<br />我之前没有排序,wa了。(╬▔ ω▔)<br /> <br />圆形的位置不好处理,我们可以考虑圆心,变成三角形来分析。<br />题目说明只有相邻层会接触。所以问题变得比较简单,而且我们可以逐层计算上去,最终得到答案。<br /><br />连接相邻的2个圆心和对应上方的圆心,显然AC=AB=2,再算 θ1 和 θ2原创 2010-08-28 10:04:00 · 2647 阅读 · 0 评论 -
1121. Tri Tiling
<br />显然 n 为奇数时,无法拼成。<br /><br />2*3 有3种排法,设f[n]为方案数,显然可以从前一个状态得到 f[n-2]*3 个排列。<br />通过观察,比较麻烦的是除了从 f[n-2] 能排出 f[n],另外一种情况是 f[n-2]再加上2格突出(如上图)。此时有2种排法能拼出 f[n](因为这两格突出可以上下翻转,共两种情况)。<br /> <br />所以我定义了两个数组,re 和unre,分别代表规则的3*n矩形的排列数和不规则(多出2格)矩形的排列数(后者不考虑上下翻转的原创 2010-08-29 10:46:00 · 2216 阅读 · 1 评论 -
1231 The Embarrassed Cryptography
<br />TAG 高精度<br />以前的经验,转换成int数组时用比较大的进制程序会比较快。比如1000进制的话,123456789转换成{123,456,789}的一个数组。<br />刚开始用了100000进制,没考虑到模除的结果比较大,用int结果会溢出的(╬▔ ω▔) wa了好多次,还查不出有什么问题。。。<br />google一下,看了某题解“不过大牛们说,百进制TLE,千进制AC,万进制WA”才恍然大悟。<br />杯具。。(╬▔ ω▔)<br />1.13s,有点慢。。。<br />/原创 2010-07-28 01:13:00 · 2033 阅读 · 0 评论 -
1091. Maximum Sum
<br />TAG 动态规划<br /> <br />设maxd[n]为前n个数的最大子序列和<br />maxd[n]=max{ maxd[n-1], sum[n]-minX } 其中,minX=min{sum[i] | 1<=i<n}<br /> <br />同理,设rmaxd[n]为从n到序列完的最大子序列和<br /> <br />则答案为max{ maxd[i]+rmaxd[i+1] },时间复杂度为O(n)<br />#include <stdio.h>const int N=50000原创 2010-07-27 17:06:00 · 1771 阅读 · 0 评论 -
1011. Lenny's Lucky Lotto
<br />TAG 动态规划<br /> <br />1.设dp[k][n]为长度为k,最大的数不超过n的序列数,也就是题目所求。<br />dp[k][n]=dp[k][n-1]+dp[k-1][n/2];<br />0 sec 416 KB<br />当n = 9, m = 2000, # lists = 19217904335640,所以得用long long,输出时用%lld<br /> <br />2.如果你设dp[k][n]为长度为k,最大数刚好为n的序列数,那你最后还得累加才能得到答案,原创 2010-07-26 22:51:00 · 1843 阅读 · 0 评论 -
1176. Two Ends
TAG 动态规划我原先还以为可以推出选排策略,结果不行。。没有规律,得用dp(‖▔ ω▔)题目有点问题,玩家2选大的牌,如果这时候两段的牌一样大怎么办? 得选左边的才能ac 题目最后说 If there is a tie, remove the left end.打平要去掉左端点的牌,牌就变奇数了? 不用处理才能ac,比如4 2 2 2 2 ,输出0。因为题意wa了几次,太无语了。。状态转移方程写起来有点乱,用语言描述算了。设dp[s][t] 从s到t玩家1最多的得分(玩家2按贪心策略)。dp[s][t]=原创 2010-07-26 16:48:00 · 1894 阅读 · 1 评论 -
1087. A Funny Game
<br />TAG 博弈<br /> <br />推了半天,越推越麻烦。决定再算出一些结果,从结果本身推。<br />1 Alice<br />2 Alice<br />3 Bob<br />4 Bob<br />5 Bob<br />6 Bob<br />7 Bob<br />…………<br />不对劲,都是Bob。。大胆提交大于2时Bob赢,AC了。。。<br />似乎出现Alice和Bob计算结果都很简单啊。。。<br /> <br />在某大牛的指点下,终于想出必胜取法。Alice取后,Bob可以原创 2010-07-25 00:23:00 · 1622 阅读 · 0 评论 -
1211. 商人的宣传
<br />TAG 动态规划 矩阵乘法<br /> <br />题目的意思讲得不是很清楚。起点是不算第一天的,路途不算时间,而且要刚好在第L天到达目的地,不能提前到达。。<br />如果一个矩阵M代表邻接矩阵,M的n次幂 M^n 便是经过n步能到达的路径数。用原始方法时间复杂度为O(n)*O(m^3 )因为我没想到log(n)次的矩阵算法,所以用了动态规划做。O(L*n^2),结果排在Status的第一页 (‖▔ ω▔)<br />转移方程<br />dp[i][j]表示走i步到达j时的路径数<br原创 2010-07-24 03:56:00 · 1752 阅读 · 0 评论 -
1137. 河床
<br />TAG 动态规划 地理学家们经常要对一段河流进行测量分析。他们从上游开始向下游方向等距离地选择了n(≤30000)个点测量水位深度。得到一组数据d1,d2,……,dn,回到实验室后数据分析员根据需要对数据进行分析,发掘隐藏在数据背后的规律。最近,乌龙博士发现某种水文现象与河床地势有关,于是他指示他手下的分析员要找出一段河流中最大高低起伏差不超过k(≤100)的最长一段。这看似一个复杂的问题,由于任务紧急,分析员来求助于你,并告诉你博士的所有数据都精确到个位。<br /><br原创 2010-07-18 04:56:00 · 2544 阅读 · 4 评论 -
1323. Switch text
TAG 水题很水的题,不过题目没看仔细,还wa了好多次。。。(╬▔ ω▔)杯具。。“If an empty or blank line is found”我是搞不清empty跟blank。。。反正就是如果读入的是一行空格,也要忽略掉。。/* source code of submission 443988, Zhongshan University Online Judge System */#include #include char str[1024];char str2[1024];原创 2010-09-19 22:18:00 · 1477 阅读 · 0 评论 -
1282. Computer Game
<br />TAG kmp<br /> <br />算是标准的kmp的题吧,不过注意 protection_dimension 的大小并没有给出,最好动态分配内存。预先开的数组如果太小会 Restrict Function。<br /> <br />我是用大数组过的。<br />/* source code of submission 443157, Zhongshan University Online Judge System */#include <stdio.h>const int N=60原创 2010-09-18 13:47:00 · 1484 阅读 · 0 评论 -
1321. Robot
<br />TAG 最短路 <br /> <br />把格按上下左右的连通性转换成图,即格子为顶点,边 (a,b) 的权值为格子b的花费。再用普通的 Dijkstra 算法就可以直接解。<br /> <br />不过这里顶点最多n=10000个,普通的 Dijkstra 算法是O(n^2) 效率太低了。可以用堆优化。<br />因为在 Dijkstra 处理时候,有3种节点已检查的节点。(升序)候选节点。未处理节点。<br />我们每次需要从2中选出路径最短的节点进行检查,然后更新2和3中的路径值,把部分3原创 2010-09-18 02:39:00 · 1567 阅读 · 1 评论 -
[转] 搞ACM的你伤不起 by Roba(附某牛腾讯悲催面试)
//哎,悲催~~感同身受啊。。里面提到的很有参考意义。。。//哥后来找到原作者的博客啦 http://roba.rushcj.com/ RoBa原创,转载请注明出处劳资六年前开始搞ACM啊!!!!!!!!!! 从此踏上了尼玛不归路啊!!!!!!!!!!!! 谁特么跟劳资讲算法是程序设计的核心啊!!!!!! 尼玛除了面试题就没见过用算法的地方啊!!!!!! 谁转载 2011-05-07 15:49:00 · 7144 阅读 · 15 评论 -
4479. Gap
新手赛的题,据说是以前4+2的。老了,都没资格参加。在大牛的指点下,用STL的set解决,嚓,这样编程实现的话简单得多啊还好以前有看那本C++ primer,不熟的话,用stl也不是那么好写滴!主要注意:set不支持随机访问。所以就只能用自增,自减来移动指针了。find查找不到返回的是“超出末端的迭代器”。注意数据的一种“情况"要考虑周全。数据类型用int就够了。原创 2011-12-19 18:08:01 · 2083 阅读 · 0 评论 -
2503 最长字符串
TAG 水题 先找出大的count,比如A,组成A B A B .... A B A 这样,A包在外面,再把多余的A加塞进去,能塞多少是多少。注意处理 max 0 的边界情况 #include //#include //const int N=205;int countA, countB, maxA, maxB, ans;int pieceA, pieceB;原创 2011-06-18 01:24:00 · 1725 阅读 · 2 评论 -
1021. Couples
TAG 括号匹配偶然发现一道自己之前没ac的题,而且都是CE。 刚好现在弄清楚了,大数组要放到main函数外。不然会有奇怪的错误。跟编译时数据的分配位置有关。 i686-linux-4.4.........crt1.o: In function `_start:(.text+0x18): undefined reference to `maincollect2:原创 2011-06-16 19:32:00 · 1680 阅读 · 0 评论 -
1297. 猴子舞
TAG 动态规划原本想用数学方法解, 构造了一下, 只能解出部分答案, 显然是有问题的....不清楚这道题能不能用数学方法解, 如果能的话可能证明也会超复杂...我的经验就是, 对于这种"数学题", 一般是可以计算机的办法"暴力"解的, 暴搜或者dp吧..先理清题意, 对于题目描述的图, 如果能保证图连通, 那就是一个环了. 因为连通性不作要求,所以实际上可以分为1个或多个环. 当然, 这里每个环至少包含2个"圈".就是求把n分成若干份,使其的最大公约数最大.dp[i][j]表示i个圈, 分成j个环dp[i原创 2011-04-15 02:58:00 · 3149 阅读 · 0 评论 -
1114 Food Cubes
<br />TAG 种子染色 Flood Fill<br />忙于课程的各种projects,好久没写acm,惭愧,写个简单的种子染色都搞得焦头烂额。哎。<br />3维的跟2维的处理起来没多大区别。<br />不过直接深度优先居然stack overflow。才 10^6啊!?<br />所以先求出坐标的取值范围,然后扩大1个单位。最后答案要减1,也就是包围food的那个空间。<br />#include <stdio.h>#include <memory.h>const int N=102;原创 2010-12-02 22:27:00 · 1903 阅读 · 0 评论 -
1172. Queens, Knights and Pawns
<br />TAG 水题 模拟<br /> <br />按题意模拟就行。不过注意能阻挡queue的是已有的棋子,而不是会被攻击的格子。用bool数组不够表示所有状态。我用char。<br />board[i][j]= {<br /> 0, (空格,安全)<br /> 1, (会被攻击)<br /> 2, (已有题目给的棋子)<br /> }<br /原创 2010-10-10 17:31:00 · 2161 阅读 · 0 评论 -
1033. City Road
<br />TAG 动态规划<br /> <br />有M*N间房子,有(M+1)*(N+1)个路口,题目求的就是从路口(0,0) 到 路口(M+1, N+1) 有多少最短路。所谓最短路,就是只能向右或者向上走。<br />设f[i][j]为到点 (i,j)的最短路径数,有 f[i][j] = f[i-1][j] + f[i][j-1] ,注意边界。<br /> <br /><br />而题目增加了big buildings后,big buildings内部的的节点是无法到达的,所以要特殊处理,如上图的原创 2010-10-03 00:24:00 · 1399 阅读 · 0 评论 -
1763. 传球游戏
<br />TAG 动态规划<br /> <br />设f[i][j] 为传 i 次,传到同学 j 有多少种方法。(小蛮编号为0)。<br />f[i][j] = f[i-1][ (j+1)%n ]+ f[i-1][ (j+n-1)%n ] ,即由相邻的同学再传一次,便能到达 j 手中。<br /> <br />#include <stdio.h>#include <memory.h>int dp[31][30];int n,m;int main(int argc, char *argv[]原创 2010-09-18 22:01:00 · 1706 阅读 · 2 评论 -
1166. Computer Transformat
<br />TAG 高精度<br /> <br />题目要求 00 的个数,其实也就是 1001 的个数。 01 才能产生 1001 , 而要产生 01,可以由 00(1001)或 1 产生,注意000能产生101010,其中有2个01,但是根据题目的转换规则,是不可能出现连续2个0以上的,所以这里不用考虑。1的个数容易求,为2^(n-1)。<br /> <br />00 (1001) ----> 01 -----> 00 (1001)<br />1<br /> <br />设f(n)为题目所求00个原创 2010-09-18 16:03:00 · 1282 阅读 · 0 评论 -
1298 数制转换
<br />TAG 数制转换<br />原先是想不用普通进制转换,用其他方法做,发现很繁琐。<br />对比一下普通的进制转换与题目的进制转换<br />数字普通3进制 题目的3进制0000 0001001 0002002 01-3010 0104011 0115012 1--6020 1-0<br />ps:csdn居然没有插入表格的功能,还得手写html代码,囧(‖▔ ω▔)<br />发现遇到2就变-,然后先前一位进一。如果n是负数,就把正数结果取反即可。即1和-互换<br />/* source原创 2010-07-17 23:31:00 · 1586 阅读 · 0 评论 -
1500 Prime Gap
TAG 数论 素数预处理把所有素数求出,用二分法求该数的下标。 0.05s 1916KB不过时间、空间复杂度好像不如延n向两端枚举。。(‖▔ ω▔),跟数据规模有关吧。。这里用了改进的线性筛法,普通的筛法因为一个数有多个约数,会被重复刷掉很多次。void makeprime(){ total=-1; memset(isprime, true, sizeof(isprime) ); for (int i=2; i程序:/*原创 2010-07-18 21:33:00 · 1792 阅读 · 2 评论 -
1888. Circular Sequence
TAG 贪心算法设数组sum记录序列和,要找一个最大的子序列,只需找出 asc=max { sum[b]-sum[a] } 0当然,还有一个问题要处理,序列接成一个圈。上面只求出一种情况,还有一种情况就是中间被舍弃,把首尾两段连接成子序列。我们只要仿照上面的方法,再求一个最小的子序列desc=min { sum[b]-sum[a] },然后用sum[n]减去desc便能得到asc。但这里注意desc的长度为1-n,总长度减去desc后的长度为 0-(n-1)。我们要去掉0的情况,补上n的情况。但具体的原创 2010-07-04 02:21:00 · 1428 阅读 · 1 评论 -
Sicily 1797. Do solve it directly
题目很长,废话很多。其实题目很简单,按题目说的做就行。直接按照公式递归做。/* source code of submission 312639, Zhongshan University Online Judge System */#includeusing namespace std;int n,a,b;int x,y,d;void go(){原创 2010-04-10 01:31:00 · 1058 阅读 · 0 评论 -
Sicily 1799. Slides
显然直接开个大数组模拟最简单,可是slide的坐标范围太大,但是slide的个数却不多, 用离散化的方法,先对坐标排序,然后重新标号。/* source code of submission 339198, Zhongshan University Online Judge System */#include#include#include#include#include原创 2010-04-10 01:16:00 · 1101 阅读 · 0 评论 -
Sicily 1800. Sequence
题意很简单,但是数据规模比较大。第一步的优化就是使用sum数组,sum[i]表示1到i的和。能快速计算其中连续一段数据之和。显然主要的操作就是对于sum[j] (j>=L),寻找最大的sum[i] ( max(0,j-U)虽然很符合RMQ算法,可是我用RMQ还是超时了。。 最后用一个priority_queue解决的。优先级队列满足我们求极值的要求。实现时,我们只需从头扫描队列原创 2010-04-10 01:57:00 · 1545 阅读 · 2 评论 -
Sicily 1798. Alice and Bob
判断n*n是否为偶数就行。简单的证明可以用1*2的骨牌布满棋盘。对方每走一步,你走1*2骨牌剩下的另一格,能保证必胜。/* source code of submission 312719, Zhongshan University Online Judge System */#includeusing namespace std;int main(){ in原创 2010-04-10 01:35:00 · 3539 阅读 · 4 评论 -
Sicily 1796. Max's kingdom
找中位数。先进行多关键字排序,然后再从头扫面一遍,统计结果。/* source code of submission 312635, Zhongshan University Online Judge System */#include#includeusing namespace std;struct node{ int p,a; bool o原创 2010-04-10 01:20:00 · 1115 阅读 · 0 评论 -
Sicily 1794. Missiles
A国有n个城市,B国有m个城市,(n>=m),给出每对城市间导弹的飞行时间,求A全歼B至少需要多少时间。显然,AB可以形成一个二分图,题目求在所有最大匹配中,最大边最小能取多少。 求最大匹配用匈牙利算法。但为了求最大边的最小值,我们可以在边的取值范围内进行二分搜索,依次调用匈牙利算法,检查是否能形成m对匹配。需要注意的是,数据给出的城市间导弹飞行时间不一定是最短的。需要对所有顶点用原创 2010-03-26 17:50:00 · 1173 阅读 · 0 评论 -
Sicily 1792. Hengheng's Problem
模拟题,先按时间段的先后排序,然后从头扫描一边寻找最大连续空闲时间段。注意不要遗漏最后边界情况。 #include#include#includeusing namespace std;struct T{ //s为开始时间,t为结束时间 int s,t;};bool cmp(const T &a, const T &b){原创 2010-03-25 01:15:00 · 1504 阅读 · 0 评论 -
Sicily 1790. Single Round Match
水题。数据比较大,显然得用高精度。#include #includeusing namespace std;int main(){ int t; char a[1004], b[1004]; scanf("%d", &t); for (int i=0; i<t; ++i) { scanf("%s%s",a原创 2010-03-25 00:35:00 · 1226 阅读 · 0 评论 -
Sicily 1793. Numbers
设x=GCD(a,b),y=LCM(a,b)。a=x*k1b=x*k2, 其中 GCD(k1,k2)=1有y=x*k1*k2; 求min(a,b),即min(k1,k2)有k1和k2两个未知数,数据规模也不是特别大,可以用搜索求解。因为只需找到min(k1,k2),我们从k1,k2最接近时开始搜索,只要找到符合条件的解便能保证最优,所以搜索量还是很小的。 #includ原创 2010-03-25 01:35:00 · 1470 阅读 · 1 评论 -
1889. Max’s game
<br />TAG 种子染色 flood fill 队列 数据结构<br /> <br />使用类似种子染色的方法,从起点开始染色,使用队列保证花费小的先染到。<br />//1.07 sec 1476 KB 2839 Bytes#include <stdio.h>#include <queue>#include <memory.h> using namespace std;const int DY[]={0, 1, 0, -1};const int DX[]={-原创 2010-07-07 09:22:00 · 1167 阅读 · 0 评论 -
1193. Up the Stairs
<br />TAG 模拟<br /> <br />题目还蛮有意思的。(^ω^) 通常这种题目不会直接模拟的,太繁琐了,肯定经过分析之后有简单的模型。<br />这里的要点就是相遇时传递箱子,两个人的角色也可以互换。<br />互换之后就变成一群人不停来回搬运箱子,同时楼梯只能同时通过一个人的限制也被“打破”了。<br /> <br />这里初始时,有拿箱子和没拿箱子其实就是初始方向不同而已。搬运第一个箱子的时间也就不同了,但后面的周期都一样。<br />这里假设能几个人接连在一起走,当作一个点来看待。比如原创 2010-07-12 23:16:00 · 1419 阅读 · 0 评论 -
1002. Anti-prime Sequences
<br />TAG 搜索 回溯 深度优先<br /> <br />之前看了这题目,毫无头绪,所以搁置了很久,到最近才ac掉。<br /> <br />这种题目,应该是没办法用数学方法推算的,就算有,我想我也推不出。不过1000个数的全排列太大了,用搜索好像又会超时。但仔细分析又发现,条件比较苛刻,all consecutive subsequences of length 2,3,...,d sum to a composite number,也就是说,从2到d的子序列都要满足,不单单d长度的。 /*我原创 2010-07-10 14:09:00 · 1905 阅读 · 0 评论 -
1024 Magic Island
<br />TAG 搜索 dfs bfs<br />深度优先、宽度优先都行。<br />因为没有用STL 用静态数组分配节点,速度很不错 0.22 sec 808 KB<br />/* source code of submission 427641, Zhongshan University Online Judge System */#include <stdio.h>#include <memory.h>const int N=10000;struct tnode {原创 2010-07-17 17:22:00 · 1513 阅读 · 0 评论