- 博客(31)
- 资源 (3)
- 收藏
- 关注
原创 不使用加减乘除符号计算加法
给定两个正整数,不使用加减乘除符号计算它们的和。方法:例如,5+17=22,5是101,17是10001。第一步各位相加得到的结果为10100(不考虑进位)---与异或操作相符;第二步记下进位,为10---可用&操作来记下;第三步把前两步的结果相加,得到10110,转换成十进制正好为22.重复上述过程,直到不产生进位为止。int add(int a,in
2013-11-30 19:42:45
2142
原创 类Nim取石子游戏
题目:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3060题意:有n堆石子,分别有个,这里,两个游戏者轮流操作,每次可以选一堆,拿走至少一个石子,但是不能拿走超过一半的石子。比如,若有3堆石子,每堆分别有5,1,2个,则在
2013-11-29 19:03:32
4978
原创 HDU3389(阶梯博弈)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3389题意:1-N带编号的盒子,当编号满足A>B && A非空 && (A + B) % 3 == 0 && (A + B) % 2 == 1则可以从A中取任意石头到B中,谁不能取了谁就输。分析: 其本质为阶梯博弈。 阶梯博弈:博弈在一列阶梯上进行,每个
2013-11-29 18:38:13
3289
1
原创 翻棋子游戏与Nim游戏
题意:一个棋盘上每个格子有一个棋子,每次操作可以随便选一个朝上的棋子(x,y),代表第i行第j列的棋子,选择一个形如(x,b)或(a,y)(其中b 分析:把坐标为(x,y)的棋子看成大小分别为x和y的两堆石子,则本题转化为了经典的Nim游戏,如果难以把棋子看作石子,可以先把Nim游戏中的一堆石子看成一个正整数,则Nim游戏中的每次操作是把其中一个正整数减小或者删除。
2013-11-29 17:06:32
3459
原创 Chomp!博弈(巧克力游戏)
有一个n*m的棋盘,每次可以取走一个方格并拿掉它右边和上面的所有方格。拿到左下角的格子(1,1)者输,如下图是8*3的棋盘中拿掉(6,2)和(2,3)后的状态。结论:答案是除了1*1的棋盘,对于其他大小的棋盘,先手总能赢。分析:有一个很巧妙的证明可以保证先手存在必胜策略,可惜这个证明不是构造性的,也就是说没有给出先手怎么下才能赢。证明如下:
2013-11-29 11:05:39
9058
原创 Ferguson博弈
清空/分割游戏也叫做Ferguson博弈。进行游戏需要用到两个盒子,在游戏的开始,第一个盒子中有n枚石子,第二个盒子中有m个石子(n, m > 0)。参与游戏的两名玩家轮流执行这样的操作:清空一个盒子中的石子,然后从另一个盒子中拿若干石子到被清空的盒子中,使得最后两个盒子都不空。当两个盒子中都只有一枚石子时,游戏结束。最后成功执行操作的玩家获胜。找出游戏中所有的P位置。
2013-11-29 10:35:47
2067
原创 圆的反演变换
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4773题意:给定两个圆,告诉半径和圆心,它们是相离的,在这两个圆外给定一个点p,求符合条件:过点p的圆且与已知的两个圆外切的所有圆的总数和它们的圆心坐标和半径。分析:根据题意,我们设已知两个圆的半径分别为和,它们的圆心分别为和,设点p的坐标为并设要求的圆的圆心
2013-11-27 14:52:47
28808
3
原创 取石子游戏与SG函数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1848题意:有3堆石子,石子数量分别为a,b,c,有两个玩家,每次只能从任意一堆中取f个,这里的f只能为fibnacci数,问是先手胜还是先手败.分析:由于石子的数量都在1000以内,那么我们可以先预处理出1000以内的SG函数值,然后对于3堆石子,我们进行异或,如果为0说明
2013-11-24 20:07:53
2346
原创 HDU1524(博弈--有向无环图SG函数)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1524题意:在一个有向无环图上有n个顶点,每一个顶点都只有一个棋子,有两个人,每次根据这个图只能将任意一颗棋子移动一步,如果到某一步玩家不能移动时,那么这个人就输.分析:本题是最典型的有向无环图的博弈,利用dfs把所有顶点的SG值都计算出来,然后对每个棋子的SG值进行异或运算,如
2013-11-24 19:15:32
3060
原创 求树的重心
题目:http://poj.org/problem?id=1655题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的.分析:首先要知道什么是树的重心,树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心.
2013-11-23 20:08:12
18613
5
原创 深度理解链式前向星
我们首先来看一下什么是前向星.前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了.用len[i]来记录所有以i为起点的边在数组中的存储长度.用head[i]记录以i为边集在数组中的第一个存储位置.那么对于下图:
2013-11-23 16:55:12
75611
76
原创 邮局--dp经典问题
题目:http://poj.org/problem?id=1160题意: 一些村庄被建立在一条笔直的高速公路边上,我们用一条坐标轴来描述这条高速公路,每一个村庄的坐标都是整数,没有两个村庄坐标相同。两个村庄间的距离,定义为它们的坐标值差的绝对值。我们需要在一些村庄建立邮局——当然,并不是每一个村庄都必须建立邮局,邮局必须被建立在村庄里,因此它的坐标和它所在的村庄坐标相同。每个村
2013-11-23 11:26:11
6567
原创 棋子--状态压缩dp
题目描述:在一个N*N的棋盘上放棋子,每一个棋子的上下左右都没有棋子,也就是不相邻,一共有多少种放法?(N sample_input013sample_output1263分析:首先,我们可以逐行来摆放这些棋子,这样我们会发现,每一行的摆放状态只和上一行有关,这样我们可以采用递推的方式来解决。 假设f[i][j]为第i行
2013-11-21 16:02:31
1962
原创 POJ2369 置换群
题目:http://poj.org/problem?id=2369题意:给定一个序列,问需要最少需要置换多少次才能变为有序序列.分析:对于每一位,算出最少的置换到自己应该的数字。每一位都有这样的数字,取最小公倍数就可以。#include #include #include using namespace std;const int N = 1005;
2013-11-21 15:06:57
2658
原创 DP之花店橱窗布置
题目:https://www.smartoj.com/p/1286分析:花瓶是有序的,花也是有序的,这就保证了有序性,从而满足子解的全局最优,和无后效性.假设dp[i][j]表示前i朵花,放在前j个花瓶里的最优值.则有:那么经过优化后得到:#include #include #include using namespace std;
2013-11-21 14:24:02
3532
原创 归并排序求逆序对
我们知道,求逆序对最典型的方法就是树状数组,但是还有一种方法就是Merge_sort(),即归并排序。实际上归并排序的交换次数就是这个数组的逆序对个数,为什么呢?我们可以这样考虑:归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两半合并起来。在合并的过程中(设l当a[i]>a[j]时,在前半部分中比a
2013-11-20 21:11:38
41772
原创 二进制位交换,反转,与统计1的个数
问题一:给一个整数v,求它的二进制表示中从右往左数第x位和第y位交换后的值(从0开始计数)。 分析:举个例子,如果v的二进制表示为XXXXaXXXXXXbX,我们交换第1位和第8位。我们是这样做的:先把这两位的值都取零后的值保存在一个变量里面,即tmp = XXXX0XXXXXX0X,然后再取ans = 0000b000000a0,那么可以看出tmp | ans就是答案了。现在关键
2013-11-13 14:18:50
3783
原创 sscanf()函数的用法
sscanf与scanf类似,都是用于输入的,只是后者以键盘为输入源,前者以固定字符串为输入源。 比如有些题目中有这样的输入:2012:12:20:Monday,现在要把它们提取出来分别处理,那么用sscanf()就很方便了。 #include #include #include using namespace std;char str[25];ch
2013-11-12 20:16:33
1970
原创 关于int main(int argc,char *argv[])
在int main(int argc,char *argv[])中的int argc和char *argv[]都是用来在命令行里传递参数。在Linux环境下用的最多,Windows环境下一般用得较少。以一个简单的例子就能说明,比如如下代码: #include #include #include using namespace std;int main(int
2013-11-12 18:52:01
2419
原创 assert()函数
assert单词是断言的意思,assert宏的原型定义在中,其作用是如果它的条件返回错误,则终止程序执行。 函数原型为void assert(int expression); 意思就是计算表达式expression,如果其值为假,那么它先向stderr打印一条出错信息,然后通过调用abort来终止程序运行。例如:int divide(int a,int b){
2013-11-12 17:10:00
1608
原创 缓冲区溢出
缓冲区溢出是指当计算机程序向缓冲区内填充的数据位数超过了缓冲区本身的容量。溢出的数据覆盖在合法数据上。理想情况是,程序检查数据长度并且不允许输入超过缓冲区长度的字符串。但是绝大多数程序都会假设数据长度总是与所分配的存储空间相匹配,这就为缓冲区溢出埋下隐患。 操作系统所使用的缓冲区又被称为堆栈,在各个操作进程之间,指令被临时存储在堆栈当中,堆栈也会出现缓冲区溢出。 当一个超
2013-11-12 16:53:31
1989
原创 字符串的距离
题目:http://wikioi.com/problem/2180/ 题意:设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩展串,这里“□”代表空格字符。如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1与B1具有相同的长度,那么我
2013-11-12 14:34:36
5473
1
原创 堆操作与堆排序
首先,我们来认识堆: 堆的建立:将给定的序列按层次遍历建立完全二叉树,然后从最后一个非终端结点开始自下向上逐步调整为堆。 这里就有两个重要的操作,shift_up(int t)和shift_down(int t),这样我们就建立了堆。对于堆排序,就相当于每次取出堆顶的元素值,这样是从大到小排序的,因为建立的是大顶堆。 现在来详细说一点:比如对于序列:5 8 9 7 6
2013-11-11 19:35:53
4821
原创 正方形个数(二维点哈希)
题目:http://poj.org/problem?id=2002 题意:平面上给定n个点,求由这些点能构成多少个正方形。 分析:我们枚举两个点,那么在这两个点形成的直线两边可以计算出正方形的另外两个点,利用Hash然后查找即可。 #include #include #include using namespace std;typedef long lo
2013-11-10 19:27:59
3469
原创 杨氏矩阵的基本操作
对于杨氏矩阵,是一种很强大的数据结构,它既可以用来当堆,又可以用平衡树的查询方法。 最常见的三种操作就是:插入,删除,查询。 对于插入操作:void Insert(int x,int y,int num){ y = min(y,a[x][0]); while(y > 0 && a[x][y] > num) y--; y++; if(a
2013-11-09 17:34:58
3067
原创 杨氏矩阵与钩子公式
杨氏矩阵又叫杨氏图表,它是这样一个矩阵,满足条件: (1)如果格子(i,j)没有元素,则它右边和上边的相邻格子也一定没有元素。(2)如果格子(i,j)有元素a[i][j],则它右边和上边的相邻格子要么没有元素,要么有元素且比a[i][j]大。 1 ~ n所组成杨氏矩阵的个数可以通过下面的递推式得到: 如图就是n=3时的杨氏矩阵。
2013-11-08 21:33:25
11286
原创 三角形内切圆的半径
已知一个三角形的三条边长分别为a,b,c,求它的内切圆的半径大小。 分析:对于这个三角形,设它的顶点分别是A,B,C,圆心为O,半径大小为r。那么过圆心作这三条边的垂线分别交AB,BC,AC于D,E,F,很明显OD = OE = OF = r,而且有:,亦即有: 从而解之, 已知三角形三边计算面积利用海伦公式:,其中
2013-11-08 21:09:05
5167
原创 codeforces 数论分析题
题目:http://codeforces.com/contest/359/problem/C 题意:给一个素数x和一个长度为n的数列a[],求的分子和分母的最大公约数。 分析:对于分子来说,我们把分子中的每一相等的项合并起来,然后相同的项必然有系数,那么所有的系数有可能也是x的倍数。那么我们把它提出来即可。#include #include #include #
2013-11-08 20:14:50
2597
原创 当鼠标滑过文本框自动选中输入框内容JS代码
代码:响应鼠标自动选中文本框内容function selectInputContent(n){ obj =document.getElementById(n); obj.focus(); obj.select();}
2013-11-07 13:35:41
3577
1
原创 stringstream的用法
C++标准库中的提供了比ANSI C的更高级的一些功能,即单纯性、类型安全和可扩展性。 >库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。 stringstream通常是用来做数据转换的,跟C库中的sprintf()差不
2013-11-06 17:10:04
1567
原创 C++中的inline函数
在函数名字前面加上inline,该函数就被声明为内置函数。每当程序中出现对该函数的调用时,C++编译器使用函数体中的代码插入到调用该函数的语句之处,而不是将流程转出去,同时用实参代替形参,以便在程序运行时不再进行函数调用。 引入内置函数的目的就是:消除函数调用时系统开销,以提高运行速度。减少程序执行过程中对CPU的中断次数。 我们知道,在程序执行过程中调用函数时,系统要将程序当
2013-11-06 14:05:07
1683
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人