随笔分类 - 算法
摘要:一个三角形由三个不共线的点组成,也就是说,三角形的个数等于三点不共线的组数。由于三点不共线的组数比较难算,可以通过计算它的补集三点共线的组数,再由总数C(n*m,3)减去。计算方法和Highway比较类似,若已知n行m列的答案,新增第n+1行,令n+1行的第一个点为a,那么a所在的三点共线满足什么条件?有多少组?几何上三点共线任意两点斜率相等,如果再加上各坐标值是整数这个限制条件,那么可得,最低点与最高点的横坐标之差与纵坐标之差非互质,即最大公约数K大于1。组数为K-1。我们可以枚举一个与a非同行同列的b,计算a与b连线上的三点共线组数。但是,跟上一题Highway一样,要考虑重复计算的问题。
阅读全文
摘要:一开始以为要用欧拉函数解决,看了半天,发现怎么套都套不上去,只好换个角度思考,由于是递推专题,就用递推的思路尝试一下,如果n行m列的所有道路都已经建好。现在新添加一行,即第n+1行,会有哪些道路需要建设?先看第n+1行的第一个点a,再选择一个非同行同列的点b,若a与b之间没有道路,需要满足哪些条件?a与b之间没有道路就必须满足a与b之间的道路没有经过其它点,即a与b之间的横纵坐标之差互质。想到这就自以为解决问题了。后来发现互质只是条件之一,若有另外一点c与a的横坐标之差和纵坐标之差都是b的两倍,那么a与b的道路就已经存在。所以完整的条件是a与b互质且没有任何一点与a的横坐标之差和纵坐标之差都是
阅读全文
摘要:250pt题意:给定两个整数以及它们的个数,求由多少个整数由它们组成的,且两个数的个数差不超过1。分析:暴力枚举。View Code class TheBrickTowerEasyDivTwo { public: int find(int n, int a, int m, int b) { int i,j,k; bool dp[10000]={false}; for(i=0;i<=n;i++) for(j=max(i-1,0);j<=i+1;j++)...
阅读全文
摘要:因为做手术,耽误了不少时间。贪心的就是选择当前最优(大,小)的,所以经常要用排序,最大堆,枚举。排序2782BinPacking选定一个,再选一个尽可能大的枚举3066Maximum这题过的糊里糊涂的,不知道是不是数据弱的缘故,每次在条件允许的范围下选择尽可能大的数2076AllRoadsLeadtoAlbuquerque,er,Rome一开始直接想的是O(n^3)的算法,想不出来。一看题解居然是从O(n^4)优化到O(n^3)的,以后直接想想不出来的话,可以先想复杂度高的,再优化。和1153类似,枚举过渡法。动态规划1784Huffman'sGreed比较经典的动态规划,除了题名,跟
阅读全文
摘要:250pt题意:给定一个字符串,求没有重复字符的最长子串。分析:直接暴力枚举所有子串(开始位置和结束位置)。View Code class ChocolateBar { public: int maxLength(string s) { int i,j,k,t,ii,flag,a[28],n=s.size(); for(i=k=0;i<n;i++) for(j=i;j<n;j++) { ...
阅读全文
摘要:250pt题意:给定二维格点图和一个在格点图中的禁止点,每个格点包含0或1,求最多有多少个1被包含在一个不包含在禁止点的矩形里。分析:以禁止点所在行,列为边界,枚举,共4种情况。View Code #include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #incl
阅读全文
摘要:250pt题意:鸡兔同笼类问题,求三种动物总数。分析:第二个变量完全没用,直接推公式可以跳过个数求总数。View Code #include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sst
阅读全文
摘要:250pt题意: 给定字符串,求使至多有一对相邻字符不同的排列数。分析: 至多有一对就说明至多只有两种字符,答案只可能是0(多于两种字符),1(一种字符),2(两种字符)。View Code #include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include
阅读全文
摘要:250pt题意:给定两个只有两种字符组成的字符串,把一个字符变成另一个字符称为一次变换,求是否能从第一个字符串经过k次变换后变成第二个字符串。分析:首先求出至少需要多少次变换m,若k不小于m且k和m的差是偶数(1个字符通过两次变换后值不变),则能,否则不能.View Code class EasyConversionMachine { public: string isItPossible(string ow, string fw, int k) { int i,j,n=ow.size(); ...
阅读全文
摘要:题意: 一个序列,开始时为1,接下来每步,该序列中的1变为01,0变为10,求第n步时序列中连续的0有多少对?分析: 令Sn表示第n个序列,~Sn表示第n个序列的反,An表示第n步时序列中连续的0的对数。 0:1 1:01 2:1001 3:01101001 4:1001011001101001 5:01101001100101101001011001101001 观察可得,Sn=~Sn-1+Sn-1; (1)当n为奇数时,Sn中连续的1和0的数相同 ~Sn的末位和Sn的首位都是0, An+1=An+An+1; (2)当n为偶数时,Sn中连续的...
阅读全文
摘要:250pt题意: 有左,中,右三个位置,一个球占据其中的一个,移动球到相邻的位置称为一次移动,求n次移动后球最可能在哪个位置(相同则字典序最小)?分析:给力的250pt,还以为要用动态规划做,因为只有三个位置,可枚举。 0,移动次数为0肯定在原位置 1,球不在中间时,第一步肯定移到中间, 2,球中间时,剩余的移动数如果为偶数,肯定会回到中间,奇数的数,因为左右对称,左边50%,右边50%,字典序小,所以是左边View Code class BallAndHats { public: int getHat(string hats, int numSwaps...
阅读全文
摘要:题意: 给定四个可以等比例缩放(缩放后长宽比不变)的矩形,求在经过缩放后是否可以完全覆盖另一个矩形。分析:知道要深搜,不敢做。。 看了解题报告的两幅图后豁然开朗,分两种,还是没用深搜; 一种是填充式,另一种是分隔式 1:填充式,每次放矩形时,放大至最大; +------------+ |111111111111| |222233333333| |222233333333| |222233333333| |222244444444| |222244444444| +------------+ 2:分隔式,2*2,每个小矩形至少和另一个有有一条公共边 +---+--------+ | ...
阅读全文
摘要:250pt数学模型: 给定一个数组,求不同整数的种数*出现次数最多的数的次数。分析: 因为数字范围有限,暴力模拟即可View Code class KingdomAndDucks { public: int minDucks(vector <int> d) { int i,j,k,n=d.size(),a[55]={0}; for(i=0;i<n;i++) a[d[i]]++; for(i=k=j=0;i<55;i++) ...
阅读全文
摘要:250pt数学模型: 求顶角是120度的等腰三角形的面积分析: L*L*sqrt(3.0)/4.0, 计算的时候为了提高精度,先乘后除。View Code class MinimalTriangle { public: double maximalArea(int length) { double l=length,t=sqrt(3.0); return l*l*t/4.0; } }; 500pt数学模型:给定n组点,每组横坐标相同,第一组:(0,1),(0,2)........
阅读全文
摘要:250pt数学模型: 给定一组数,求出现次数最多的数,若不唯一,取在数组中索引值的最大值最小的数。分析:因为次要条件比较麻烦,数组遍历从末尾开始可轻易解决。View Code class ContestWinner { public: int getWinner(vector <int> events) { int i,j,n,k,c,m=0; k=0; n=events.size(); for(i=n-1;i>=0;i--) { ...
阅读全文
摘要:题意: 给定一个有n*m的个网格的方块,蛇是由连续的网格组成的序列,并具有以下两个属性。 1,组成蛇身的网格的值为1; 2,蛇的每个格点附近(北/东/西/南)有且仅有有两个格点是1(蛇头蛇尾除外);不能在蛇头和蛇尾增长的,能增长但会违反蛇的两个属性或碰到另一条蛇,称为最长蛇。求最长蛇的数量。分析:1,判断是否是蛇;2,,判断在首尾两端增长时是否会合法(用扫雷游戏的手法来做,即求出每个格点的四 周的1的数量)结:一直不能清晰的复述题意是迟迟做不出的这题的主要原因View Code #include<cstdio>#include<cstring>#include<c
阅读全文
摘要:题意: 科学家用机器人探险地下洞穴,但是机器人只有一个存储器,每到一个洞穴,就会记下洞穴的名字,当有多个洞穴可以进入时,总会选择最左边没有进入过的洞穴,当可选择的洞穴都进过时,他会后退,任意两个洞穴之间只有一条路径,当机器人回来时,科学家根据存储器发现洞穴的结构不是唯一的,他们想知道有多少种可能的结构。数学模型: 已知一棵树的深度搜索的节点(包括回退)顺序,求树的总数。分析: 因为答案很大,肯定不可能一一枚举; 设f[i][j]表示从i个点到j个点所能构成的树的总数; 通过枚举回退点来重叠计算,以回退点为根(起点,回退点,终点必须相等),,f[i+1][k-1]*f[k][j]; ...
阅读全文
摘要:数学模型: 已知一个n*m的国际象棋的棋盘,有qn个皇后,kn个骑士,pn的士兵(士兵不能动),士兵不能动,皇后和骑士的走法不变,求棋盘有多少格子没被占用和被皇后和骑士攻击到。分析: 因为皇后的走法覆盖面较广,所以给每个格子设四个标记,表示是否被皇后的四个方向的攻击到,因为状态数少,可以按位标记,来整合成一个整数,分别为1,2,4,8。View Code #include<cstdio>#include<cstring>#define MAXN 1010using namespace std;struct Piece{ int row,col;};Piece Q[MAX
阅读全文
摘要:数学模型: 已知n,求n中取k(k<=n)个数组成的m(m<=n)个的集合的排列数.分析: 因为是统计个数,和求组合数类似(见波利亚的解题法表),方法也差不多; f[i][j]表示的i个数组成j个集合的个数; 如果第i个数是单独成一个集合,有j个位置可以插入,f[i-1][j-1]*j; 如果第i个数是插入已有的j个集合,f[i-1][j]*j; 算完之后n个数取k个的组合数.View Code #include<cstdio>#include<cstring>using namespace std;int main(){ long long i,j,m,d
阅读全文
摘要:题意: 统计两个整数a,b之间各个数字(0~9)出现的次数,如1024和1032,他们之间的数字有102410251026102710281029103010311032总共有10个0,10个1,3个3等等。分析: 因为前导0的干扰,为了计算方便暂时都先计算在内,之后再减; 如果是0~199,那么百位上的0和1各出现一次,s剩下的就是两个00~99,总共两百个二位数,而每个数出现的次数都一样,都是2*(99-00+1)/10; 那么任意的数都可以分解成类似的数字,如3426,则可以分成0000~2999,3000~3399,3400~3419,3420~3426几个部分各自计算,再求和...
阅读全文