上一页 1 ··· 37 38 39 40 41 42 43 44 45 ··· 85 下一页
  2012年2月24日
摘要: HDU_1848 用记忆化搜索的方式处理出sg函数值,然后看sg[n]^sg[m]^sg[p]是否为0即可,推荐一个讲SG函数入门知识的博客:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561007.html。#include<stdio.h>#include<string.h>#define MAXD 1010int f[20], h[MAXD][20], sg[MAXD];void prepare(){ int i; f[0] = f[1] = 1; for(i = 2; i <= 15; i ++) f. 阅读全文
posted @ 2012-02-24 12:41 Staginner 阅读(270) 评论(0) 推荐(0) 编辑
摘要: HDU_1536 比较直观的思路将每一堆的sg函数计算出来,然后看所有的sg函数异或之后是否为0。但实际上我们没必要每一堆都独立计算一遍sg函数,因为游戏规则是一样的,所以sg函数也必然是一样,所以只用开一个一维的sg[]数组记录sg函数的值即可。 此外,一开始调用一下类似dp(10000)的递归函数企图预处理出sg[]的所有值的想法是错误的,因为假定初始石子是10000个的话,有些情况是可能取不到的,比如样例1,假定初始石子是10000个的话对于9999个石子的情况就没法取到。所以一个比较好的方式就是采用记忆化搜索的形式,用哪个就搜哪个。 用于记录后继结点sg函数值的数组最好开成静态的放在递 阅读全文
posted @ 2012-02-24 11:50 Staginner 阅读(325) 评论(0) 推荐(0) 编辑
摘要: HDU_1850 这个相当于有M个子游戏,每个子游戏的SG函数简略写一下之后也比较容易搞出来,最后会发现sg[i][Ni]=Ni,那么如果所有的sg[i][Ni]异或以后的结果为0,是必然会输的。 接着我们考虑先手必赢的情况,如果从一堆中拿走一些石子后,能使得sg异或值为0的话,就算有一种方案,同时根据x^x=0的原理,对于第i个石堆,我们可以先将其余石堆的sg函数的异或值算出来,这样就得到了第i个石堆需要变成多少个石头才能必赢,如果要变成的这个数量比石堆原有的石子数量小的话,就说明存在一种方案。 上面的做法是O(n^2),原因在于我们每次都算了一遍其余sg函数的异或值,但实际上是是没有必.. 阅读全文
posted @ 2012-02-24 09:53 Staginner 阅读(389) 评论(0) 推荐(0) 编辑
  2012年2月23日
摘要: HDU_1874 终于找到了一个题目练了一下刚刚学习的用SG函数求解的方式,推荐一篇讲SG函数入门知识的博客:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561007.html。#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 1010int d[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};int N, sg[MAXD];int dfs(int n){ int i, j 阅读全文
posted @ 2012-02-23 22:58 Staginner 阅读(265) 评论(0) 推荐(0) 编辑
摘要: HDU_2147 这个题目写得太悲剧了,本来我想找个简单点的题目实践一下刚接触的sg函数的,结果一开始没注意到空间的限制,开了二维的sg数组记忆化搜索结果就爆了空间了。 然后不得不换成了递推的模式继续写,而且还要用滚动数组优化内存,但写完交上去TLE了。 那没辙了,找规律吧,然后画了一下5*5的情况就找到规律了,然后直接O(1)求解过掉了。 囧,写到最后几乎跟sg一点关系都没了……继续找别的题目练习sg函数……#include<stdio.h>#include<string.h>int N, M;void solve(){ int ok; if(N & 1) o 阅读全文
posted @ 2012-02-23 22:36 Staginner 阅读(252) 评论(0) 推荐(0) 编辑
摘要: HDU_2489 由于N很小,可以枚举保留的顶点的情况并依次计算最小生成树,然后更新一下记录的结果即可。#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 20#define MAXM 400int N, M, u[MAXM], v[MAXM], w[MAXM], vis[MAXD], r[MAXM], node[MAXD], p[MAXD], e, wa[MAXD], wb[MAXD], *a, *b, ew, nw;int cmp(const void *_p, const 阅读全文
posted @ 2012-02-23 11:51 Staginner 阅读(260) 评论(0) 推荐(0) 编辑
摘要: HDU_2492 由于N比较大,枚举两个队员并计算其中有多少个裁判是行不通的,不妨换一种思路去枚举裁判,这样对于任意一个裁判而言,不同的比赛场数等于左边小于裁判skill rank的人数乘以右边大于裁判skill rank的人数,再加上右边小于裁判skill rank的人数乘以左边大于裁判skill rank的人数。 在计算人数的时候,可以维护记录分别记录左右两边各个skill rank的人数的两棵线段树,每当枚举一个裁判时,先将裁判从右边的线段树删去,计算完之后再将裁判添加到左边的线段树中。#include<stdio.h>#include<string.h>#def 阅读全文
posted @ 2012-02-23 01:24 Staginner 阅读(335) 评论(0) 推荐(0) 编辑
摘要: HNU_10694 这个题目本质上就是去求模p的原根。 首先,我们用反证法证明这个结论:如果对于任意的正整数i,r^i%p包含了1~p-1所有整数的话,那么满足r^i%p=1这个等式的最小正整数为p-1。 如果上面的命题不成立,不妨设满足r^i %p=1这个等式的最小的正整数为j,假如j<p-1,那么对于任意r^i总能分解成若干r^j的与r^x(x<j)的积,所以r^i%p最多有x个不同的值,那么r^i%p不可能包含了1~p-1所有的整数。假如j>p-1,那么就说明当1<=x<=p-1时,不会出现a^x%p的值为1,那么就必然有x1、x2(1<=x1< 阅读全文
posted @ 2012-02-23 00:04 Staginner 阅读(367) 评论(0) 推荐(0) 编辑
  2012年2月22日
摘要: HNU_11720 这个题目本来是一个数论课本的课后习题,最后可以得到结论sp=(p*p-1)/24-(p-1)/4(我暂时还没看懂怎么推导的……),这样就可以很容易的算出sp的值,于是就可以得到sp*rp=k*p+1,变形得sp*rp-p*k=1,又因为p是素数且可以证明gcd(sp,p)==1,所以这个方程必然有解,于是用拓展欧几里得求出rp即可。#include<stdio.h>#include<string.h>long long int P;void gcd(long long int a, long long int b, long long int &am 阅读全文
posted @ 2012-02-22 20:01 Staginner 阅读(197) 评论(0) 推荐(0) 编辑
摘要: HNU_11722 由于勾股数a,b,c可以表示成a=m^2-n^2,b=2*m*n,c=m^2+n^2,因此可以枚举n找到所有可能的互素的勾股数,然后去掉其中重复的解即可。 这个题目还可以用一个剪枝,就是如果c%4!=1的话一定无解。#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXD 60000int C, a[MAXD], b[MAXD], r[MAXD];int gcd(int x, int y){ return y == 0 ? 阅读全文
posted @ 2012-02-22 12:58 Staginner 阅读(298) 评论(0) 推荐(0) 编辑
上一页 1 ··· 37 38 39 40 41 42 43 44 45 ··· 85 下一页