ACM
PYB不开心
这个作者很懒,什么都没留下…
展开
-
筛选平方因子
给定范围[m,n],求出里面所有不含完全平方数因子的数!解析:首先筛出所有2到m−−√2到\sqrt{m}的素数p,然后对每一个P2P^2的倍数进行标记(代表删除),最后没有标记的就是我们需要的数。def erase(m): p = [] vis = set() for i in range(2,m+1): if i in vis:continue原创 2016-11-26 21:51:29 · 691 阅读 · 0 评论 -
算法竞赛入门经典:第6章例题
例题1:模拟并行程序的运行,采取双端队列来运行。主要考虑到以下几个逻辑问题:(1)(1)首先要注意当前剩下的时间是不是还够运行该条命令。不够的话就要结束当前的循环且不能删除该条命令。即便是end命令可能也不够时间完成!(2)(2)如果该程序是正常结束,就不要将该命令入队列,或者如果该命令是因为被锁住而退出循环,也不能入队列。注意不能用剩余时间来判断,因为有可能使执行lock命令之后时间刚好为0,然后原创 2016-07-11 22:03:31 · 532 阅读 · 0 评论 -
算法竞赛入门经典第6章例题(2):二叉树部分+四分树
6−66-6这是一道有关二叉树的1题目,但是如果你真的对它用二叉树进行模拟就入坑了,不需要真正的实现二叉树,也无关小球的编号大小,我们只需要判断第i次小球在第d层的行为既可。假设向左为0向右为1,这个行为序列的规律是:000,100,010,110,001,101,011,111。即第k位每2k−12^{k-1}变动一次,根据这个规律,我们可以直接求解最终的位置。def get_track(i,D)原创 2016-07-21 17:35:50 · 656 阅读 · 0 评论 -
算法竞赛入门第五章习题分析(部分)
这个题目不难,关键是理解题意,注意到是每一个单词的左边界的都要对齐而且要尽量往左靠,一开始我看成每一行了,结果写了半天觉得不对劲。有一个细节要注意,在使用split()进行分割时,会将空字符串也放进去,我们需要进行判断,如果遇到空字符就跳过。另外就是对每一列的最长单词进行统计,这样我们才能够对齐单词。def format_print(): line = input() words =原创 2016-06-08 21:47:15 · 476 阅读 · 0 评论 -
算法竞赛第五章例题分析(Python实现):
例题5-1:Uva10474,非常简单的题目,但是我尝试用python来读取控制台的输入发现并不方便,比如要按照空格分开读取就会很麻烦。。。其实真正的核心代码就5行左右…def Find_Marble(): def getdata(): data = input() x,y = data.split() return int(x),int(y)原创 2016-05-08 14:58:05 · 1980 阅读 · 0 评论 -
算法竞赛入门第五章(竞赛题目选讲)解析:
例题5-8,此题不难,关键在于将files排序后能够找到对应的列数和行数(行数要小心n是cols倍数的特殊情况,所以要用n-1去除),然后按行输出。因为是列优先,所以索引的求解变成j*rols+i。def format_files(files): M = len(max(files,key = lambda x:len(x))) def Print(s,extra):原创 2016-06-04 16:22:08 · 432 阅读 · 0 评论 -
算法竞赛入门经典第四章:部分习题解答
跳过了部分习题。。。习题4-2:此题不难,我采取最直接的办法,暴力遍历进行判断,代码如下:def do_squares(h,v,n):#h,v是一个矩阵 def test(i,j,l): _i = i;_j = j while(_j<j+l): if(h[_i][_j]==0):return False _j+=原创 2016-05-07 14:26:38 · 805 阅读 · 0 评论 -
算法竞赛入门经典第四章例题总结:
计算组合数def cnm(n,m): if(m < n-m): m = n-m a = 1;b = 1;ans = 0 for i in range(m+1,n+1): a *= i b *= (i-m) print(a//b)cnm(21,1)这道题本身很简单,但是一个注意一点,利用m猜测字谜游戏:输入单词和猜测,并输出结果。题目非原创 2016-04-28 20:56:40 · 824 阅读 · 0 评论 -
算法竞赛入门经典第三章总结(2):后半部分习题解答
UVA232:题目就不写了,主要是模拟单词的变换.注意必须要按照启示格的顺序来输出.在输出竖的单词时候要用一个矩阵来标记是否被访问过.当然还可以按照竖的方式写入然后再排序.def cross(matrix,r,c): mark = [[0]*c for i in range(r)] def test(i,j):#检查一个白格是不是启示格 #if(matrix[i][j原创 2016-04-28 11:19:03 · 360 阅读 · 1 评论 -
BFS求解N数码(python)
import os import time N = 9 T = [1,2,3,4,5,6,7,8,0]#the original state obj = [2,4,3,1,6,0,7,5,8]#the final state factory = [1, 1, 2, 6, 24, 120,720, 5040,40320] def formed_print(L): n = 0;原创 2016-03-04 19:53:31 · 853 阅读 · 0 评论 -
算法竞赛入门经典第6章:图论基础
6.126.12用DFS求连通块。这种算法也叫种子填充,每一次找出一个连通块,直到不存在连通块为止。利用DFS进行8个方向的遍历。def proc(graph): visited = [] buf = [] cnt = 0 def inbound(x,y):return x<m and y<n and x>-1 and y>-1 def init(m,n):原创 2016-07-26 11:57:08 · 578 阅读 · 0 评论 -
算法竞赛入门经典第6章图论和树:竞赛选讲部分与习题
6−176-17给定如下输入,输入每一组数据的表达式。2 A |--------B C D | |----- - E F G#e|----f g这道题目就要直接在输入的字符数组里面递归遍历,如果想要将输入标准化之后再处理会发现特别的麻烦,各种小细节容易弄错,所以遇到这种情况就直接在原始输入里面递归就好,不需要建树。buf = ['' for i in range原创 2016-07-29 19:29:21 · 639 阅读 · 0 评论 -
求出n个互异的数使得最小公倍数等于所有元素之和
(1)(1)方法1:这个是看了别人的办法得到的启示,对于任何一个n元组,假设其满足题意,设lcm(a1...an)=∑ni=1ai=xlcm(a1...an)=\sum_{i=1}^na_i=x.则考虑添加两个k1x,k2x使得n+2元组依旧满足k_1x,k_2x使得n+2元组依旧满足,其实这里问题转换成:寻找一个包含1的三元组,1,k1,k2满足题意1,k_1,k_2满足题意,这里利用到了如何求n原创 2016-08-08 23:06:15 · 547 阅读 · 0 评论 -
Uva1609:Boring的序列(有相当难度的好题!)
这道题的意思是:给定一个序列,如果任意字序列里面都有至少一个不重复的元素(不重复相对于子序列),那么我们就叫这个序列是不无聊的。我们需要检测一个序列是否满足这种性质。这道题首先是有O(n^2)的解法的,枚举任意子区间然后判断,但是判断这个操作为O(n),我们需要将其降为O(1).方法是用滑动窗口来维护信息,并且时刻维护不重复元素的数量。当然这种方法很直观,但是效率太低。考虑有没有O(NlogN)的算原创 2016-11-22 10:08:19 · 917 阅读 · 0 评论 -
滑动窗口问题
给定一个序列,求出一个字序列ALAR没有重复的值。这个题目看似非常简单,但是却很经典,值得反复捉摸。首先,最简单的办法就是用一个大小为k(k从大到小,发现符合条件的就可以停了)的窗口开始扫描,O(n^2)可以解决。左出右进。但是这个效率还是太低了。其实我们可以对比一下leecode上的最大长方形问题,有没有发现有一点相似呢,我们也是不断拓展右边界(只要可以递增),如果不能拓展了,就“滑动窗口”使得最原创 2016-11-18 22:42:58 · 3812 阅读 · 0 评论 -
Maigc Cubes:2017 Works Application笔试
给定一个M*M*M的魔方,和N个小魔方,将每一个小魔方融合到大魔方里(小魔方的大小不确定,但是一定小于大魔方),融合的部位将将加起来再对P取余,要求最后的结果一定是全部为0。求出所有小魔方的位置。思路如下,这个题目似乎没有找到巧妙的解法,所以采用暴力搜索.但是搜索也是有技巧的,我思考之后发现:这个问题很适合双向BFS搜索加减枝。从最终状态全0出发,我们可以每次减去一个魔方的值然后取余(-1%3 =原创 2016-10-31 11:00:11 · 2069 阅读 · 0 评论 -
算法竞赛入门第七章:竞赛选讲(Uva12325,Uva1603)
宝箱Uva12325:宝箱 Uva12325:这道题很有思维强度,首先比较容易想到的是枚举宝箱的数量,从0到[n/s1]或者0到[n/s2]。但是由于输入很大,当s1,s2都很小的时候,那么枚举的数量将会非常的巨大。因此针对s1,s2较小而n很大的情况,需要提供另一种思路。另一种枚举的思路是从s1,s2入手的。因为s1,s2很小,如果枚举的数量和他们成正相关,那么就可以确保枚举的效率。考虑一个事实:原创 2016-09-06 11:29:32 · 1177 阅读 · 0 评论 -
算法竞赛入门第七章(1):暴力枚举
例题1例题1:此题比较简单,先写一个10取5的排列函数(可以适用其他的排列),然后进行进行查表。当然如果解约空间就可以直接循环加判定字母是否重复来解。def create(m,obj = list(range(10))): def remove_2(x,L): L = L[::] L.remove(x) return L ans = [原创 2016-08-14 19:20:27 · 552 阅读 · 1 评论 -
算法竞赛入门第七章:迭代加深搜索
埃及分数问题,对于任意分数ab\frac{a}{b},都可以写成∑1xi。其中xi互不相同。需要求出一个组合,其中项数最少。若项数一致,则需要最小的分数最大\sum\frac{1}{x_{i}}。其中x_i互不相同。需要求出一个组合,其中项数最少。若项数一致,则需要最小的分数最大思路分析:思路分析:理论上来说,回溯法可以暴力解决问题,但是解答数的项数太多,广度和深度都是无限的。对于稍微复杂一点的数据原创 2016-09-03 19:59:30 · 1906 阅读 · 0 评论 -
算法竞赛入门第七章:回溯与路径寻找
PrimeRing,Uva524:Prime Ring,Uva524:基本思路:直接回溯即可。注意一个细节每一个长度为n的环对应n种排列,因此输出要求固定第一个值为1。Primes = set([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31])def is_prime(x): return x in Primesvis = [0] * (16 + 2)C =原创 2016-08-29 20:49:15 · 829 阅读 · 0 评论 -
算法竞赛入门第七章:习题
uva208本题相对简单,只要提前从k做一次bfs,这样可以判定是否某个节点与k相连。然后开始进行dfs,注意这里的dfs需要将整个解答树展开完毕。def search(graph,k): def find_connect(): connects = set([k]) q = deque() q.append(k); while原创 2016-09-11 22:52:02 · 321 阅读 · 0 评论 -
算法竞赛入门第七章(2):枚举排列和子集
可重复集的排列:可重复集的排列:有几点要注意(a):(a):首先对序列进行排序,然后枚举时候要跳过相同的元素。(b):(b):由于存在相同的元素,因此枚举时要判断是否该元素已经全部用完了。(c):(c):最后得到的结果是按照字典序从小到大的排列,同时相对以前直接传递参数保存剩下元素的方法来说:空间需求大大减少,但是时间消耗有所增加,当然还有很多可以优化的地方,比如统计元素的出现次数,可以提前计算好。原创 2016-08-14 20:53:34 · 496 阅读 · 0 评论 -
A*求15码
import osimport timefrom functools import reduceN = 16T = [4,7,8,3,6,13,15,2,1,11,5,12,0,14,10,9]#T = [1,2,3,4,5,0,7,8,9,6,10,12,13,14,11,15]#obj = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]#obj =原创 2016-03-04 23:05:26 · 499 阅读 · 0 评论 -
再次探究复制问题的解法.
如何将一个字符迅速复制粘贴到N个字符?同样采取动态规划的方法,但是这次的方法更加基础和容易理解.虽然效率变差了.我们将建造一个状态空间,它有两个变量,当前的字数和粘贴板上面的字数.可以考虑到所求为F[N][M],M应该小于等于N/2;注意到当M<N/3时,它可能是由F[N-1][M]写入一个字符得到,也可能是由F[N-M][M]进行一次粘贴得到.当M>N/3时,它只可能是由F[N-1][M]得到的.原创 2015-11-26 15:18:09 · 305 阅读 · 0 评论 -
poj1753解题报告(2):BFS
摘要:这是第一次学习使用c++STL中的queue,感觉知其然不知其所以然,不过基本用法了解了.很方便,不用自己定义队列ADT了.用0-65535代表所有的状态,首先检测初始状态,因为后面的程序不会检测它.如果不满足,那么就进入循环(BFS),每次出队一个状态,然后进行决策得到下一个状态,然后判断这个状态是否符合条件,如果符合,就直接输出(由于BFS,一定是最小的),否则判断该状态是否已经访问过,如原创 2015-09-11 21:20:26 · 353 阅读 · 0 评论 -
poj2255:从先序和中序找后序
摘要:本题也是一个水题,但是题目中输入到文件末尾结束把我难住了.我们如果单独输入一个回车是不会结束循环的,因为cin会读入回车,它依然是一个有效输入,好办法是输入ctlr+z就会终止循环.这个在poj上会帮你自动弄好的,只是在本地调试时需注意.基本思路简单,就是利用递归的思路首先从一个先序里面找到根,然后在中序里面通过根找到左右子树,将根入栈,最后递归的遍历右子树,左子树(注意顺序).最后出栈即可.原创 2015-09-11 14:23:16 · 368 阅读 · 0 评论 -
poj2996解题报告
大致题意是输入一个象棋的类似棋谱,然后按要求输出棋子的位置,白棋行小的先输出,黑棋行大的先输出,相同行的列小的先输出.+---+---+---+---+---+---+---+---+|.r.|:::|.b.|:q:|.k.|:::|.n.|:N:|+---+---+---+---+---+---+---+---+|:p:|.p.|:p:|.Q.|:p:|.R.|:::|.p.|+---+-原创 2015-09-25 15:05:20 · 341 阅读 · 0 评论 -
poj1503
摘要:123456789012345678901234567890 123456789012345678901234567890 123456789012345678901234567890 0output:370370367037037036703703703670基本思路很简单,就是简单的进位,注意最后一次进位要特殊处理.(1)要特殊注意的几点[1]可能输入是最大的9999…9999(10原创 2015-09-10 23:19:48 · 527 阅读 · 1 评论 -
poj2262
摘要:本题不难,但是一定要注意的时间界的限制.基本的思路一定是从两边往中间开始扫描,这样可以可以确保获得的素数值之差最大.但是如果只是这样做是通不过时间测试的.经过参考别人的代码,我发现尽管理论上的时间界是一样的,但是在实践中还是可以提高速度.改进:因为用了isprime这个自定义函数,当测试很大的数的时候,它的开销是很大的.我们应当尽可能的减小对大的数进行检查.如果以从3开始的小素数开始检验,我们原创 2015-09-10 00:10:14 · 459 阅读 · 0 评论 -
POJ编译错误
在VS2010上编译是正确的,但是进入POJ的线上编辑界面却失败,失败的原因是找不到头文件”stdfax.h”。经过查找发现该头文件不是标准的c++头文件,但是缺少该文件在VS上不能通过编译.解决的办法是将代码复制到poj的编辑界面上时去掉这个头文件,但是注意要包括新的头文件如iostream或者stdio.h都可以.然后在该编译器上九可以运行成功了.原创 2015-09-09 14:22:44 · 2002 阅读 · 0 评论 -
poj739
判断一个数(1,1000)能够写成几种连续素数之和的形式这道题很简单,如果输入量很大就用筛法把所有素数(1,1000)求出来.如果输入不大,就写一个isprime函数直接判断,没有太多可说的内容.代码:首先找到一个最小的尚未被删除的素数,记录它,然后删除它的所有整数倍数.int j = 2, t = 0; int Isdeleted[1000] = {-1,-1}; while(j<原创 2015-09-09 18:51:01 · 283 阅读 · 0 评论 -
poj3299解题报告
摘要:给定3个参数 H,D,T 中的两个,根据公式humidex = temperature + h h = (0.5555)× (e - 10.0) e = 6.11 × exp [5417.7530 × ((1/273.16) - (1/(dewpoint+273.16)))] 求解另外一个参数. 输入以单个的E作为一行结束. Sample InputT 30 D 15 T 30.0原创 2015-09-09 14:17:28 · 471 阅读 · 0 评论 -
poj1083
摘要:本题不难,主要要注意将两边的房间区分开来来算,计算每个走廊区间上需要经过次数最多的那个地方,这就是代表走完所有路径需必须要走的次数.明显的,该次数就是总共走的次数的下界,现在需要证明的是走N次一定能够将所有路线都走完.证明:假设在区间[a,b]上重叠了n个路线,那么可以证明,从对于其中任何一个路线,可以将与其不冲突的路线一起走完,对于区间[a,b],冲突的路线就少了一次.对于不经过[a,b]的原创 2015-09-09 21:59:31 · 321 阅读 · 0 评论 -
poj2965解题报告
摘要:这个题和翻棋盘的题目几乎一样,注意差别在于需要输出路径,因此DFS使得编程方便.注意如果使用BFS,你很难去记录每条路径上所做的决策.#include "iostream"#include "string.h"using namespace std;int minroute[16],board[16];int Minstep = 17;bool success(){ for原创 2015-09-12 11:05:15 · 381 阅读 · 0 评论 -
poj1753解题报告(1):DFS算法
摘要:选择一个棋子,它和它周围的所有棋子都要翻转一次。求最少要几次可以解决,如果不能解决输出impossible.这个问题没什么太好的办法,基本上就是枚举法,首先我们选择深度搜索优先(DFS)来解决问题.基本思路就是每次选择一个棋子进行翻转(或者不翻转),如果该棋子已经翻转过,就不需要继续翻转了.检测是否已经达到目标,如果超过16次都没有达到目标,那么它就不可能达成.同时这个题目还给了我一个教训,忘原创 2015-09-11 19:13:58 · 945 阅读 · 0 评论 -
poj3006
摘要:这题本身简单,但是暴力破解很可能超过时间界.最好的选择是采取素数筛法,以空间换时间,这样所有的素数都可以用O(1)的时间测出来.#include "stdafx.h"#include "iostream"using namespace std;bool Isprime[1000005];void Find(int a,int d,int n){ int x = a - d,co原创 2015-09-11 12:02:39 · 246 阅读 · 0 评论 -
poj1062解题报告:
Description:年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:”嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。”探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或原创 2015-10-11 15:06:29 · 904 阅读 · 0 评论 -
poj2632(模拟题)
摘要:本题难在麻烦二字,主要是需要注意第一次碰撞之后立刻要停止模拟.利用vector容器简化代码.#include "stdafx.h"#include "iostream"#include "vector"int test = 0;using namespace std;const char S[4] = {'N','W','S','E'};int board[101][101] =原创 2015-09-21 22:24:47 · 326 阅读 · 0 评论 -
poj3259:spfa解法
构建一个队列,将松弛成功且不在队列的点放入队列,每次出队一个点.直到队列为空,如果队列中的某个入队次数超过n次,就说明存在一个负环.#include "vector"#include "queue"#include "iostream"using namespace std;const double inf = 10000000;struct node{ int end;原创 2015-10-09 16:36:49 · 442 阅读 · 0 评论 -
poj3259解题报告
题目等价于判断图里面是否存在一个负环.首先可以采用bellman_ford算法,但是该算法需要一个起始点,而这里是需要判断整个图是否存在负环.因此可以假设有一个源点,假设它与其他所有点连通,并且花费都是0.这样就可以直接调用bellman_ford算法,如果原来的图存在负环,那么它一定也在新的源点所在的连通图里面.#include "vector"#include "iostream"using原创 2015-10-09 15:23:09 · 348 阅读 · 0 评论