随笔分类 -  算法竞赛入门经典

摘要:数学题(字符串的解码与编码,涉及组合数学)题意:给你一个字符串,它们的全排列中有一些字符将会是回文串,单独把这个些回文串拿出来,按字典序给他们从1开始编号。然后输入数字n,把第n个回文串输出。这题第一次看完全不会放下几天,今天再看瞬间想通。首先这题要从回文串的性质分析:一个回文串如果长度为偶数,那么可以确定,每种字符的个数一个是偶数,不会有字符的个数为奇数。如果一个回文串为奇数,那么可以确定,一定有且仅有一种字符的个数为奇数,其他字符的个数都会偶数,而且整个回文串中间的那个字符必定是为奇数的那个字符。所以对于长度为奇数的回文串,我们可以暂时除掉中间的那个字符(因为它是固定一定要在那里,没什么研 阅读全文
posted @ 2013-02-04 11:53 Titanium 阅读(356) 评论(0) 推荐(0)
摘要:数学题(概率题)题意:有牛和车躲在门内,你做一个选择,但是还不能看答案,然后知情人会帮助你,你会打开几个门里面全是牛,但是注意一点,知情人知道你选的那个门里面是牛还是车,但即便他知道是牛他也不能告诉你。知情人打开门后,你必定重新选择另一个门(要是可能保持不变的话又不同了),问你这次选到车的概率多少这题一开始看错题意,想了很久觉得这题怎么这么难,后来才搞清楚其实就是一不计算输入a,b,c, a牛,b车,知情人会一次性打开c个门(注意是一次性全部打开c个门,要是一次打开一个的那完全不同了,另外还注意一点,如果你选的就是牛,虽然知情人能打开c个门,但是它不能打开你那个,而题目有一个条件 0<= 阅读全文
posted @ 2013-02-03 21:16 Titanium 阅读(498) 评论(0) 推荐(0)
摘要:数论题:幂取模给出a和n,求a^n的前3位和后3位关于求后3位,就是一个二分并且模1000即可,至于怎么求前3位,需要一些数学分析我们来看一大数nn可以写成n=10^b,这个a是个小数所以b=i+d,i是整数部分,d是数部分则n=10^(i+d)=10^i * 10^d这里很重要,10^i其实有什么用?i是整数,所以10^i一定是1000…………000,然后*10^d,d是一个小于1的小数(别忘了是b的小数部分)所以决定n这个大数会出现什么数字的,是10^d,10^i只是给10^d起到往后移动小数点的作用所以我们要知道10^d另外我们知道0<=d<1,所以 10^0 <= 1 阅读全文
posted @ 2013-02-03 18:29 Titanium 阅读(408) 评论(0) 推荐(0)
摘要:数学题(我更觉得是恶心模拟)题意很清楚,就是给一个高精度整数,求它的平方根,数据保证一定是整数解这个东西要用高精度各种搞(看过别人的报告说有些不用高精度,没心机看下去,自己硬是写了一堆高精度),主要就是模拟手算的方法手算的方法这里说得很清楚了(希望看得到图片吧)开根方法笔算开根法: 例1:求①将37625从个位起,向左每两位分一节:3,76,25②找一个最大的数,使它的平方不大于第一节的数字,本题中得1(1的平方为1,而2的平方为4,大于3,所以得1).把1写在竖式中3的上方。③将刚才所得的1平方写在竖式中3的下方,并相减,然后将76移写在本行(如图)④将前面所得的1乘20,再加一个数a,写在 阅读全文
posted @ 2013-02-02 21:37 Titanium 阅读(1295) 评论(0) 推荐(0)
摘要:数学题(组合数学 或者 DP递推都可以)题意就不说了比较好懂。这题如果按照题意去模拟着思考是很难解决的,我们换一种思维,抓住一个特殊条件,将问题进行转化。无论是组合数学的方法计算还是DP递推,都是转化问题后才进行的。我们看做有n个不同的盒子,很t个完全相同重量为1的球。按照题意,每个盒子的重量不能小于p,那么我们干脆先每个盒子都放p个小球。剩下m=t-n*p个小球。那么无论这m个小球怎么放都是符合要求的。所以问题就转化为,将m个完全相同的小球放在n个不同的盒子里,盒子内可以装一个或多个小球或者为空。组合数学:即便是“将m个完全相同的小球放在n个不同的盒子里,盒子内可以装一个或多个小球或者为空” 阅读全文
posted @ 2013-02-02 13:17 Titanium 阅读(409) 评论(0) 推荐(0)
摘要:数论题:线性方程看了《数论概论》的相关章节-《线性方程与最大公因数》首先是要证明一个方程必定有整数解ax+by=gcd(a,b); 为方便 g=gcd(a,b), ax+by=g这个证明有些复杂就不写了,而如何构造一个可行解(x1,y1)其实也在证明过程中在得到一个可行解后就可以得到无数组解,他们是(x1-k*(b/g) , y1+k*(a/g)) , (其中g=gcd(a,b),k是整数)而对于方程ax+by=c,只要c是g倍数那么就有整数解,否则没有看完原题,p是x/k的下整,q是x/k的上整,然后p*m+q*n=x,这个方程其实就是ax+by=c的形式,而且这个方程一定有整数解因为d=g 阅读全文
posted @ 2013-02-01 20:14 Titanium 阅读(834) 评论(0) 推荐(0)
摘要:数学递推(DP)题意:有n个人,身高各不相同排成一列。从前面 看过去能看到p个人,后后面看过去能看到r个人。矮的人会被高的人挡着看不到。问满足p,r的情况下,有多少种排列的可能。/*DPdp[i][j][k]表示队列中有i个人,从前面可以看到j个人,后面可以看到k个人有多少种可能策略:从空队列开始,往其中插入人,从最高到最低插入,每次插入有3种位置,一种在队首,则从前面看的人数会加1,一种在队尾,则从队尾看的人数会加1,一种在中间(已经有n人在队中,那么有n-1个插入位置),则从队首和队尾看的人数 都不会增加状态转移方程 dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][ 阅读全文
posted @ 2013-01-28 17:17 Titanium 阅读(258) 评论(0) 推荐(0)
摘要:数论题、参考了 http://blog.csdn.net/clevermike/article/details/8177450这道题的详细分析在黑书中(221页,第2章,数学方法与常见模型)先看代码,代码中有注释//费波那列素数定理//费波那列素数:若某个费波那列数和比它小的所有费波那列数互质,则称它为费波那列素数//若a是b的倍数,则fa是fb的倍数//所以提示我们费波那列数和它的下标有关//从第5个费波那列书开始,某项为费波那列素数当且仅当它的项数为素数//其中最开始两个特殊的,第3,4项fib为2,3,它们是费波那列素数//后面的则是第5,7,11,13,17,19,23,29…………… 阅读全文
posted @ 2013-01-23 18:49 Titanium 阅读(562) 评论(0) 推荐(0)
摘要:数学题(找规律或者是递推)一个大饼,切n刀,大饼最多能被分成几分(每份大小可以不一样)其实只要在纸上画几个出来就能找到规律了。用文字来描述的话就是,在已经切了n刀的情况下而且是最优的,切第n+1刀怎么切还能最优呢?就要第n+1刀能和之前的n刀全部相交。递推公式为 f[0]=1; f[n]=f[n-1]+n (n>=1); 两者结合得 f[n]=(n*n+n)/2+1 (n>=0);#include <cstdio>#include <cstring>long long n;int main(){ while(scanf("%lld",&a 阅读全文
posted @ 2013-01-23 11:56 Titanium 阅读(217) 评论(0) 推荐(0)
摘要:数学题:给你一个区间[a,b]在该区间内有多少个费波那列数(包括a,b),数据规模达到10^100。这题的原理很简单,基本没什么算法,其实更偏重于编程能力,需要用到高精度。另外找区间的地方要小心1.先把长度在100以内的fibs先找出来并保存,再开始输入case2.得到区间[a,b],那么在保存下来的fibs里找到 第一个f[p],要满足a<=f[p] , 然后继续找下去,找到 第一个f[q],满足b<=f[q]其中f[q]还要处理一下,如果b=f[q],那么f[q]显然在区间内 ; b<f[q],那说明f[q]并不在区间内,由于是第一个所以可以知道f[q-1]一定要区间内而 阅读全文
posted @ 2013-01-22 22:48 Titanium 阅读(436) 评论(0) 推荐(0)
摘要:数学题(找规律题)题意:给你骑士的攻击范围,给你一个r行c列的棋盘,问怎么放能放最多的骑士而且任意骑士间不会相互攻击r行c列和c行r列是相同的,所以我们在计算的时候,先转换使 行<=列 ,这样方便计算当1行是,整行都能放完当2行时,放满一个田字,隔一个田字……大于两行时,每行都是隔着放——第奇数行从第一个开始,第偶数行从第二个开始这题以前做过简易版的,选成这个也差不多,不过以前没有思考过1行的特殊情况,也没有详细思考2行的特殊情况#include <cstdio>#include <cstring>int main(){ int r,c,n,m,ans; whil 阅读全文
posted @ 2013-01-22 20:54 Titanium 阅读(488) 评论(0) 推荐(0)
摘要:数学题题意很好懂,就不解释。这个代码写得不好,主要是自己想复杂了感觉,或者还没有找到最本质的规律,举个例子来说明思路23 ,456781. 处理为30 ,45670 ,另外的部分就单独计算得到是78,接着就是(45670-30)/10*45=2053802.变为3 ,4567,处理为10,4560,另外的部分单独计算为70,接着就是(4560-10)/10*45=204753.变为1,456,处理为10,450,另外的部分单独计算为66,接着就是(450-10)/10*45=19804.变为1,45,处理为10,40,另外的部分单独计算为60,接着就是(40-10)/10*45=1355.变为 阅读全文
posted @ 2013-01-22 18:32 Titanium 阅读(453) 评论(0) 推荐(0)
摘要:数论题题意:有无限的水供应,另外有AB两个杯子,他们有容量,分别为ca和cb,满足0<ca<=cb,并且ca和cb互质一开始两个杯子都没有水。一种操作是,你能往一个杯子加水,但必须把这个杯子加满,一种操作是倒水,但一定要把水倒空,一种操作是把一个杯子的水倒给另一个杯子,但要求是至少使一个杯子为空或者另一个杯子。现在给你一个数字n,n<=cb,现在的任务是使B杯的水量为n,至于A杯的水量是多少都行,问你要怎么做。这题对于一个case其实有多种答案,不过题目对于输出并没有要求并没有需要优化,任意一组可行解即可这题一开始没有头绪,从推理的角度来看这题,但是一直找不到出路。题目归类在 阅读全文
posted @ 2013-01-21 13:08 Titanium 阅读(377) 评论(0) 推荐(0)
摘要:数学题(模运算)题意:详细的翻译http://www.cnblogs.com/devymex/archive/2010/08/28/1810480.html简单的题意:给你一个字符串(可能有空格,最多1024字符),每个字符代表一个数字,因为最多有256个字符,所以这个字符串其实是表示一个256进制的数字。但这还没完,在这个256进制数字要再加两位,组成一个新的256进制数字,这个数字要能被g=34943(这是个十进制数字)整除,要你输出新添加的那两个数字是什么,这两个数字要以16进制的形式输出,用空格隔开思路:把原来的256进制数字先转为十进制数x,那么再添加两位后,其实原本的数字翻了2倍, 阅读全文
posted @ 2013-01-19 20:00 Titanium 阅读(286) 评论(0) 推荐(0)
摘要:数论题(筛法求救欧拉函数)题意:输入n,[1,50000],定义一个二元组(x,y),满足1<=x,y<=n , 且x和y互质 , 要求输出二元组的个数。注意好像(2,3),(3,2)算作两个答案,所以我们只要求出一组答案再乘以2即可关键是怎么找出这个二元组,其实就是筛法求欧拉函数我们约定x<y且x与y互质,那么我们将y从1枚举到n,对于每个y,找出所有小于它并且与它互质的x的个数,这不就是求y的欧拉函数吗?而y从1到n,不就是求n以内所有数字的欧拉函数吗?所以最后的答案,就是n以内每个数字的欧拉函数值的累加和*2-1,没什么减1,是因为一个特殊的数字1,1的欧拉函数值为1( 阅读全文
posted @ 2013-01-18 23:54 Titanium 阅读(538) 评论(0) 推荐(0)
摘要:数论经典问题:构造本原勾股数组(PPT):a^2+b^2=c^2 , 其中a,b,c两两互质题意:给你一个n,让你找出一些勾股数组,a^2+b^2=c^2 , 需要满足a<b<c<=n 。 对于每个case题目首先需要你输出这些勾股数组中PPT的个数,然后再输出一个数字,这个数字是n-所有勾股数组用掉的数字个数例如:103,4,5 是唯一一组PPT解,所以第一个输出的数字是1而另外的勾股数组包括 6 8 10 。 那么一共用掉的数字有3,4,5,6,7,8,那么没有用到的数字有4个,所以第二个数字输出4————————————————————————————————题意说完了 阅读全文
posted @ 2013-01-18 20:52 Titanium 阅读(626) 评论(0) 推荐(0)
摘要:数学题题意(就是因为读错题意而wa了一次):给一个数字n,范围在[1,2^23-1],这个n是一系列数字的最小公倍数,这一系列数字的个数至少为2例如12,是1和12的最小公倍数,是3和4的最小公倍数,是1,2,3,4,6,12的最小公倍数,是12和12的最小公倍数………………那么找出一个序列,使他们的和最小,上面的例子中,他们的和分别为13,7,28,24……显然最小和为7这个题目一开始没有头绪,写了一个暴搜程序来找答案,然后一目了然首先假设我们知道了一系列数字a1,a2,a3……an,他们的LCM是n,那么什么时候他们是最优解呢,当他们两两互质的时候为了方便我们以两个数来说明问题。a和b的L 阅读全文
posted @ 2013-01-18 11:29 Titanium 阅读(2073) 评论(0) 推荐(0)
摘要:DP构建(仿照Floyd)这题说难挺难的,现在想想好像也不太难,是因为想复杂了。其实这题的要求不算多,它仅仅是要求最后转换回到出发时的那种硬币并且获利大于0.01,而转换次数不能超过n次,转换次数越少越好,然后输出最短的路径。注意:题目并没有说要你获利最大,只是是获利>=0.01即可,另外题目对路径并没有什么特殊要求,仅仅是要求不能超过n,在路径长度相同的情况任意一条都可以的。所以我们就抓住一点:转换次数!!!!!!也就是说每转换一次,我们就去找所有的货币,看他们回到自己的时候那些货币的获利已经大于0.01了,如果有货币的获利已经大于0.01了,那么我们的算法就结束了,就输出这种货币的转 阅读全文
posted @ 2012-12-26 19:55 Titanium 阅读(1287) 评论(0) 推荐(0)
摘要:DP(类似于矩阵链乘法)我们以sample来说明问题长度100,切的地方为25,50,75.那么无论怎么切最后都是剩下四段 [0,25] , [25,50] , [50,75] , [75,100]把它们连续的两两合并的话就能得到上一层的状态,好像[0,25]和[25,50]合并,就得到[0,50],也就是说从[0,50]变到[0,25] , [25,50],花费是多少呢,就是50所以说到这里,也差不多了,状态转移方程为 dp[i][j]=min{ dp[i][k]+dp[k][j]+(y-x)} (k是i和j之间的一个数)这样子的话,我们的目标状态就是dp[0][len],即原来的整一条的费 阅读全文
posted @ 2012-12-26 13:37 Titanium 阅读(459) 评论(0) 推荐(0)
摘要:数学题(概率基本知识+DP记忆化搜索实现)题意:概率题:丢n个骰子,和大于等于x的概率是多少,用反面来求,1-小于x的概率首先丢n个骰子,可以看做是依次丢的(独立重复试验),每次丢的点数记录下来,比如3个筛子123和132是不同的,所以就是一个排列(而不是组合),那么总的可能为6^n,要用long long 保存。然后再找出有多少个排序和和是小于x的。这个找特殊排列的过程用DP来构建才不能超时(我用的是记忆化搜索,当然递推也是可以的,仿照记忆化搜索来写的,个人更倾向于记忆化搜索,容易理解,而且应该很多没用的状态不会去到,但是递推会推出所有状态)记忆化搜索,开一个二维数组dp[i][j],表示现 阅读全文
posted @ 2012-12-25 21:02 Titanium 阅读(353) 评论(0) 推荐(0)