URAL 做题记录 V2
来源:互联网 发布:单片机电子琴程序 编辑:程序博客网 时间:2024/05/02 01:51
对于上面算法的一些说明
1100:由于待排序的元素个数相当多(最多150000个),这些元素值的分布却很集中,只有1到100。因此,常规的不稳定的排序方法在这里是不适用的。我们应该反复对这些元素进行统计,第一次统计值为100的,第二次统计99的……这样一来,算法的时间复杂度大约是M*Max(N),完全可以接受。
1102:对于这类匹配问题,最容易想到的方法便是动态规划。但是由于动态规划在滚动的时候涉及到一个指针和取模的运算,而且对于给定的字符是一一匹配的,因此效率比较低。较好的方法是所谓“语法图”的办法。可以先把所有的“单词”分解为“词根”,然后用一个图表示词根之间的相互关系。因而我们可以把对字母的操作转化为对词根的操作。这样一来,判断的效率自然提高不少。
1103:这是一个相当不错的几何问题。首先,我们可以过两个点取一条乘托直线(即所有不在线上的点都在线的同侧),设这两个点为A,B。对于其他所有点Ki(i=1,2,...,n-2),我们求出角AKiB的大小。由于任三点不共线,任四点不共圆,因此这些角AKiB的大小肯定不等。因此我们可以把这些角排序。又由于圆内角>圆周角>圆外角,所以假设大小恰好位于中间位置的角为AKjB,则A,B,Kj即为所求。
1107:我们不难发现任何两个“相似”的集合除以(n+1)的余数一定不等。而商店又至少有n个,所以……
1109:也是匈牙利算法,不过不涉及带花树,因此比较简单。
1111:值得注意的是,题目并没有说所有正方形的边都和x,y坐标轴平行。
1115:先把队列按长度排序,然后采用“双重深度优先搜索”即可。当然,这个题目还可以用随机化算法。
1116:我们可以开一个大数组,模拟两次定义的情况,最后做统计即可。值得注意的是,我们应该用数组的a到b-1元素表示区间[a,b)。
1124:我们把每个盒子看作一个点,如果盒子i里存在不属于这个盒子,而属于盒子j的木块,我们就在i,j之间连一条有向边。那么我们只用统计一下这个有向图至少要用多少笔才能画成(就是欧拉路径问题)。
1126:最好先建一个哈希表,然后记录数值的分布情况。然后每次在哈希表中检索即可。
1143:这个题乍一看是NP问题。但是稍加思考我们不难发现,最优的路径一定不自交。因此实际上这个题目是可以动态规划的。
1145:这个题目考察的主要是空间的优化。首先,我们应该用一个Byte存储8位0/1,这样就可以把整个地图存储下来。然后,就可以用一个递归的过程搜索结果。递归的时候同样要注意空间的优化。1153:这个题目相当于求一个数x,满足1+2+3+...+x=m。即x(x+1)/2=m,x(x+1)=2m。又因为x^2<x(x+1)<(x+1)^2,因此我们大可不必解方程,直接用x=Trunc(Sqrt(2m))就行了。剩下的问题就是高精度开平方,建议采用二分求精的办法做。
1155:这是一个相当不错的题目,数学意味很浓。而解这个题目的核心是——染色法!首先,我们可以把这个立方体的8个顶点染成红色和蓝色,要求与红色顶点相邻的必须是蓝色顶点,反之亦然。然后,我们不难发现每次操作必然是同时改变红色顶点和蓝色顶点中的粒子数量。所以假如一开始红色顶点中的粒子总数跟蓝色顶点中的不等,问题一定无解——否则一定有解。有解的时候解的构造就比较简单了,大家自己动动脑筋吧! :p1182:首先,我们分析一下分组的要求:
1、把所有的人分成2组,每组至少有1人;
2、每组之间的人两两认识。
非常明显,如果存在两个人A和B,A不认识B,或B不认识A,那么A和B一定不能分在同一组。因此,我们以人为结点重新构造一个图G。假如A和B不能分在同一组,那么就在G中增加一条无向边(A,B)。这样,我们就得到了一个较为“单纯”的模型。下面我们对这个模型进行简单分析。
我们先研究G的一个连通分量K1。对于这个连通分量,可以先求出K1的生成树T1。对于K1中的任意结点a,假如a在T1中的深度为奇数,我们就把a加入点集S1;否则我们把a加入点集S2(S1,S2最初为空集)。显然最后S1,S2的交集为空。
不难证明,如果存在不同结点p和q,p和q同属于S1或S2,而且G中存在边(p,q),那么要做到满足题目要求的分组是不可能的,应输出No solution。否则,我们就得到了连通分量K1的唯一分组方案:分为S1,S2两组。
对于G中的每个连通分量Ki,我们可以求出相应的S1i,S2i。最后,我们的目的是把全部人分为2组。也就是说,对于i=1,2,3,...,m,我们必须决定把S1i中的人分到第1组,S2i中的人分到第2组,还是做刚好相反的处理。由于题目要求最后两组的总人数差最小,我们可以用动态规划的办法来确定究竟选取上面的哪种决策。
不妨假设G中共有m个连通分量,记|S1i|=xi,|S2i|=yi(i=1,2,3,...,m)。我们用f[i,j]表示把前i个连同分量分为2组,且这两组总人数差的绝对值恰好为j是否可能。如果可能,f[i,j]=true;否则f[i,j]=false。初始条件是f[0,0]=true, f[0,x]=false(x=1,2,3,...)。然后我们可以按照如下方法确定f[i,j](0<i<=m, j>=0):
f[i,j]= f[i-1, j-Abs(xi-yi)] or f[i-1, j+Abs(xi-yi)];
当然,在求解的同时,我们可以记录路径。最后,res=min{i: f[m, i]=true}即为最佳分组的人数差,而它对应的路径就是我们要求的分组方案。
- URAL 做题记录 V2
- URAL 做题记录
- 做题记录
- leetcode 做题记录
- 做题记录
- 做题记录
- 做题记录
- 每日做题记录
- 做题记录
- 【】做题记录
- KMP做题记录
- uva题目做题记录
- DomiNo Grid做题记录
- 【4-29做题记录】
- 【5-4做题记录】
- leetcode 做题记录2
- 机房日常做题记录
- leetcode 做题记录3
- 创建XMLHttpRequest对象
- JQuery中对option的添加、删除、取…
- 程序员的十层楼(6~7层)
- 做自己认为正确的事
- 查询sql执行情况
- URAL 做题记录 V2
- photoshop不自动刷新的问题
- Scintilla开源库使用指南(二)
- 查询时截取字符串
- 反思2011
- 不经意间的悔恨
- c语言中的回调函数
- BigDecimal 除法操作
- struts2 action跳转到action