随笔分类 - 算法
摘要:SRM545250pt题意:给定一组数,求这组数中是否存在一个数等于所有其它的数按位与(&)的值。分析:因为a&b<=min(a,b)h和a&a=a,所以就是求这组数所有的数按位与之后的是否等于最小值。View Code class ANDEquation { public: int restoreY(vector <int> A) { int i,m,k,n=A.size(); m=*max_element(A.begin(),A.end()); for...
阅读全文
摘要:250pt简单题,但很容易错。正确率只有19%题意:某国正进行选举,选民有10000,不投票和多投票都算作弊。给定n个候选者的四舍 五入后的得票率,求是否有人在作弊。算法:贪心分析:求10000是否能组成该投票结果的所需最小人数和最大人数写的时候只考虑小数点后一位,相当于考虑1000,10000人的话应该是小数点后两位500pt当时想到了,却证明不了也就不敢做,,后来还是不知道怎么证明ADD:因为胶水可以无限使用,无论怎么切,只要切得次数一定,剩余的废料拼成的木板的长度也就一定题意:需要dc块长度为dl的木板,在需要长度为al的木板最少的条件下,求切割的最少次数,可用胶水粘合切下来的木板合成所
阅读全文
摘要:题意:给定一个表达式,去除所有能去掉的括号分析:因为是表达式,所以想套用LR(1)分析法和分解表达式,一步一步手动模拟去括号,结果总是拆东墙补西墙,搞不出来。三天后看解题报告,标程是通过加括号来解决的,构造一颗二叉树,去掉所有括号,叶子是变量,非叶子其他的节点是运算符,节点的深度和他所在的括号数相同,由于*和/的计算优先级比加和减高,所以当非叶子节点的运算符的优先级比孩子节点的高时,必须通过加括号来维护pascal的标程是错(虽然它的文件名已经含有bug的单词,但是错的怎么能放到标程里!),有两处错误,我都发现过,可都只改了一处来测试,耗了一个下午,看到java版的编程才恍然大悟,不自信啊!第
阅读全文
摘要:题意:一张CD上有n首频率为f[i],长度为了l[i]的曲子,因为CD不能随机播放曲子,想播放第i首时,必须依次播放前i-1,b[i]=f[i]*(a[1]+...+a[i]),sum=b[1]+..+b[n],求使sum最小的歌曲排列方式。分析:因为1<=n<=2^16,时效只可能是O(nlogn)或O(n),一开始以为是按频率排序,发现测试数据都过不了。若已得到最优排列,使最优值为mb[i+1]+b[i]=f[i+1]*l[i]+(f[i+1]+f[i])*(l[1]+...+l[i-1])+f[i+1]*l[i+1]+f[i]*l[i];若交换f[i]*l[i+1]+(f[i
阅读全文
摘要:数据量比较大的并查集一开始一直RE,提取字符串中的整数时出错了,换种方法就AC了思路:路径压缩的并查集一个小优化(766ms)挤进第一版:合并集合的时候始终以把较大的数的集合并到较小的数的集合#include<cstdio>#include<ctype.h>#include<algorithm>#define MAXN 6000010using namespace std;int set[MAXN];int Find(int x){ if(x==set[x]) return x; set[x]=Find(set[x]); return set[x];}voi
阅读全文
摘要:模式搜索?:匹配任何字符*:匹配任意个字符,包括零个建立模式串的字典树,用并查集合并相同模式串查询的时候深搜任何可能#include<cstdio>#include<algorithm>#include<cstring>#define MAXN 100010using namespace std;int n,m;struct Trie{ int i; Trie *a[28];};Trie root;char p[7],s[22];int set[MAXN];bool mat[MAXN];void Insert(Trie *rt,int k,int j){ i
阅读全文
摘要:比赛后才做的250简单题View Code #include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <sstream>#include <map>#include <set>#
阅读全文
摘要:题意概述:用罗马数字在堆栈里进行四则运算解决思路:用贪心模拟阿拉比数字和罗马数字之间的转换,细节Code Length居然排第一!除0出错的时候0要出栈,WA了一次 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 char s[8]="IVXLCDM"; 6 int b[7]={1,5,10,50,100,500,1000}; 7 8 int ToDec(char *str) 9 {10 int n,k,i,j,c[33];11 n=(int)strlen(str);
阅读全文
摘要:题意:从一种状态通过若干个需要能量操作转换成力另一种状态所需最少的能量。一开始以为是位DP,后来发现位数(20)位太多,只能广度搜索,偷了一下懒,直接用优先队列,一开始没用pair,只保存状态,WA了3次。pair的大小是先比较first再比较second#include<cstdio>#include<cstring>#include<queue>#include<utility>#include<vector>using namespace std;typedef pair<int , int> Word ;int o
阅读全文
摘要:Trie树POJ 1451 T9题意:模拟用9个键的手机进行输入的,每输一个字母,输出最可能匹配的单词。一开始想用链表储存所有的单词,写的时候才发现连链表维护,实在太麻烦了,而且效率又不高。对于固定的输入,只用输出一个最可能匹配的词,所以不用保存所有的单词,只用保存频率最高的词就可以了。两个单词的前缀可能重叠,所以要预处理,使任何单词或前缀只插入一次。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MAXN 1010 5 using namesp
阅读全文
摘要:最长上升子序列类动态规划dp[i] = min(dp[i],dp[j] + k)题意:给定若干单词,把它们排成每行字符数为n的若干行,词与词之间可填充任意个空格,设某个单词与单词之间的空格数为g,(g-1)^2称为坏点, 求使所有坏点和最小得排版方式.技巧:因为要构造字母序最小的最优解,所以可以从后往前进行DP计算View Code #include<cstdio>#include<cstring>#define MAXN 10010using namespace std;char word[MAXN][82];int a[MAXN],aft[MAXN],b[MAXN]
阅读全文
摘要:题意:Alice和Bob在玩一个游戏,该游戏需要n个杯子和一个石头,开始时石头被罩在在某个杯子里,Alice可交换任意两个杯子,经过一系列的交换,由Bob猜石头在哪个杯子里,交换总共m步,但Bob只看到了其中的k步,问Bob猜哪个杯子的可能性最大。第一感觉就是和组合(在n个数里取m个有多少种)很相似,再看题目因为顺序是一定的,即选了k步之后,顺序只有一种。c[n][m]=c[n-1][m-1]+c[n-1][m];具体编码的时候只考虑到交换的两个杯子而忘记其他杯子在选择时的值也要加上c[n-1][m-1];#include<cstdio>#include<cstring>
阅读全文
摘要:题意:给定一个集合,有两种操作,插入一个数和查询集合中第i小的数,i每次查询一次前自增1,初始为0.一开始想先离散化,再用桶来表示这个集合,用树状数组维护查询,后来发现实现起来相当麻烦,而且思路也不够清晰。一看discuss居然有人用线段树做,简单多了,查询和插入都是O(logn);复杂度:O(nlogn);#include<cstdio>#include<cstring>#include<algorithm>#define MAXN 30010using namespace std;struct ST{ int l,r,v;//v保存是的左子树有多少个数}
阅读全文
摘要:题意:在一个长方形区域用n条直线分隔成n+1个部分,给定m个点,求这个区域的m个点,求点所在的部分。算法:二分搜索,点和直线的位置关系1,设直线的方程ax+bx+c=0(a>0);若点(x0,y0)代入方程: 若ax0+by0+c<0,则点在直线的左侧; 若ax0+by0+c=0,则点在直线上; 若ax0+by0+c<0,则点在直线的右侧; 但是前提是a>0,否则结果左右对调(WA了一次).2,(x1,y1)和(x2,y2)为某直线的两个点,直线的方程就可以表示为(y2-y1)(x-x1)-(x2-x1)(y-y1)=0; 因为n较大,而直线与直线对点具有序的关系,即点
阅读全文
摘要:表达式求值.程序套用的是poj 2252Equation Solver的标程,写的相当漂亮,简洁所有的表达式求值问题都可以用这种方法解决算法:ELL(1)-Parser2106 Boolean Expressions范式:Expression := Term { ('+' | '-') Term }Term := Factor { '*' Factor }Factor := Number | 'x' | '(' Expression ')'Number := Digit | Digit Number
阅读全文
摘要:有两个字符串A和B,求多少对属于A的子串组成B。若组成B的其中一个子串等于B[0...i](0<=i<n),那么另外一个就等于B[i+1...n-1].所以总共有n-1种形式。那么其实就是求B[0...i]和B[i+1...n-1]的值,之后再利用乘法原理求出答案。既然是两个串的模式匹配,KMP算法就再适合不过了。KMP算法的核心在于p[]数组,p[i]指的是s[0...p[i]]等于s[i-p[i]...i]。#include <cstring>#include <cstdio>#include <algorithm>#define MAXN
阅读全文
摘要:昨天做两场线上比赛,FOJ和SOJ,都只做了两题。FOJProblem 2074 Number of methods(数学)有一排石子,每次只可取走一个,第一次可取任取一个,之后取被取走石子相邻位置的石子,有多少种取法?一开始还看错题意,没注意"只能取被取走石子相邻位置的石子",WA了一次。若有n个石子,我们取走第i个石子,左边剩下i-1,右边剩下n-i个石子,之后我们每次只能取左边最右边的石子或右边最左边的石子,左边要取i-1次,右边要取n-i次,总共要取n-1次,若设左取一次的代号为0,右取一次的代号为1,取法就是一组由i-1个0和n-i个1组成的组合数。 Proble
阅读全文
摘要:2912 Average distance求一棵树的所有任意点对的距离之和总体思路是砍叶子节点,直到根节点。一开始想复杂了,不仅要记录点数,还要记录剩余的路径数,搞了一个晚上都没搞出来。睡觉的时候想到只用记录已删的点数就够了。O(n)#include<cstring>#include<cstdio>#include<algorithm>#include<cstdlib>#define MAXN 10010using namespace std;struct Graph{ int next,vex,dis;};Graph g[MAXN<<
阅读全文
摘要:3008 Gold Coins(刚开始以为会超时,会有数学方法,网上搜索了一下居然都是深度搜索)分解质因数之后深度搜索如果没有1 ≤ t ≤ n 这个条件可以直接用数学方法计算View Code #include<cstring>#include<cstdio>#include<algorithm>#include<cstdlib>#define MAXN 10010using namespace std;long long ans,n,k;long long a[MAXN],b[MAXN];void DFS(long long i, long
阅读全文
摘要:一条没有重复顶点的路径称为简单路径,求一幅无向图中不在给定两个点之间简单路径的点的个数。如果存在一条有重复顶点的简单路径,那么在这条路径上必然有环,而环上的点数(除了重复顶点)就是一个结果集。把重复顶点断开,环上的点就会被孤立。枚举所有点断开,再深度搜索,哪些点访问不到,就是所要求的目标点。O(N^3)View Code #include<cstring>#include<cstdio>#define MAXN 110int n;bool visited[MAXN],is[MAXN],a[MAXN][MAXN];void DFS(int v){ visited[v]=t
阅读全文