- 博客(80)
- 收藏
- 关注
原创 01背包变化2
题目:poj2184题意:给出num(num解答:把前面那个变量看成背包的容量。后面的值看成背包的价值。由于背包的容量可能为负值,因此需要将其向右平移100000个单位。#include#include#include#includeusing namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 110;in
2016-09-02 20:57:14
362
原创 0/1背包变化
题目:poj1837题意:有一个天平,天平左右两边各有若干个钩子,总共有C个钩子,有G个钩码,求将钩码全部挂到钩子上使天平平衡的方法的总数。其中可以把天枰看做一个以x轴0点作为平衡点的横轴。解答:dp[i][j]表示放入前i个钩码平衡度为j的种数。因为数组下标不能为负数所以把-7500到7500平移到0到15000.状态转移方程见下表。#include#include#includ
2016-09-01 20:29:31
399
原创 博弈总结
1.巴什博弈:一堆石子,每人一次从一堆石子(n个)中拿走1到m个,谁先拿光谁赢。 结论:如果石子数n模(m+1)是0.那么是奇异局势(先手必败),否则先手必胜。 另外:如果先拿光的那个人输的话,那么(n-1)%(m+1)为奇异局势。2.威佐夫博弈:两堆石子,每人每次从任意一堆中拿任意个或者同时从两堆石子
2016-08-31 19:16:27
351
原创 博弈综合
题目:hdu5754题意:有4种操作分别是:1.king.每次横或者竖或者斜只能走一步2.rook(castle).每次横或者竖能走若干步3.knight.每步先横(竖)走一格,再斜走一格。或者每步先斜走一格,再横(竖)走一格4.queen.每次横或竖或斜走若干步然后这些操作对应的是国际象棋里面的一些操作(具体操作可以百度) 然后现在我们站在(1,1)点,要去往(N,M)点
2016-08-30 21:38:51
497
原创 带环的博弈and对称性
题目:hdu3951题意:有一圈硬币有n个。每个人每次可以拿连续的1到k个。谁先拿完谁赢。解答:n k =1:看奇偶 其他情况:!!!!!第一个拿完之后就变成了一条链。这时候第二个人把这条链分为相同长度的两个部分。然后先手拿啥他就对应的拿啥。 因为:sg值一样的两个游戏处于必败状
2016-08-28 20:37:05
505
原创 状态压缩与求sg函数
题目:hdu5724题意:给定一个n*20的棋盘,棋盘上有若干棋子。如果一颗棋子右侧为空,则只可以向右移动一格,若非空,则可以移到第一个空的位置,两人轮流操作,不能操作者为输,问先者是否有必胜策略。解答:注意到棋盘只有20列,则可以用状态压缩存储当前的状态。预处理出所有状态的sg值。然后n个抑或一下就好了。我的代码(每次递归求出当前的sg值):#include#include#
2016-08-28 19:46:21
472
原创 带一个圆环的尼姆博弈
题目:hdu3980题意:有一串含有n个珠子的链子。每个人每次只能给相邻的m个珠子涂色。谁先不能涂了谁就输了。解答:重点:第一个人涂完之后它就变成了一条直线。然后每次在直线中选m个连续的涂完剩下两条抑或一下就行。#include#include#include#include#includeusing namespace std;const int MAXN = 1010;
2016-08-28 15:06:09
567
原创 斐波那契博弈
题目:hdu2516题意:有一堆个数为 n 的石子,游戏双方轮流取石子,满足:1. 先手不能在第一次把所有的石子取完;2. 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。约定取走最后一个石子的人为赢家,求必败态。解答:如果n为斐波那契数则先手必败,否则先手必胜。#include#include#include#includ
2016-08-28 13:29:12
717
原创 求sg值以及找规律
题目:hdu1079题意:随机给一个日期,两个人轮流计数,可以将月份加一,也可以将日期加一,但是要符合日期的客观规律(即要考虑平年闰年和日期进位下的进位情况),如果是2001年1月31日则日期+1后变成 2001年2月1日,因为2月没有31天故不可以将月份加一。先到达2001.11.4的获胜。解答:方法一:求sg值。#include#include#include#include
2016-08-27 22:05:22
844
原创 求sg值——分析与找规律
题目:hdu1517题意:你和一个人玩游戏,给你一个数字n,每次操作可以从2~9中任选一个数字,并把它与p相乘,(游戏开始时p=1)两人轮流操作,当一个人操作完后p>=n,这个人就是胜者。解答:方法一:写个求sg值的函数,然后找规律。 方法二:首先,有以下结论:1.任意操作都可将奇异局势变为非奇异局势。(必败状态转换为必胜状态)
2016-08-27 17:08:48
1116
原创 找数列中小于某个数的数有多少个
题目:http://codeforces.com/contest/706/problem/B题意:找数列中小于某个数的数有多少个解答:二分。。#include#include#include#includeusing namespace std;const int maxn = 100000 + 10;int a[maxn];int h[maxn];int l[ma
2016-08-26 23:53:42
1831
原创 Nim游戏、斐波那契数列和求sg值
题目:hdu1848题意:Nim游戏。每次只能拿斐波那契数列中的数。解答:dfs求sg函数值#include#include#include#include#includeusing namespace std;const int MAXN = 1100;int a[MAXN],sg[MAXN];int m,n,q;void init(){ a[0] = 1
2016-08-26 21:12:14
594
原创 nim游戏求先手第一步走的方法
题目:hdu1850题意:nim游戏求先手第一步走的方法解决:先处理出所有数抑或的值。然后再跟每个数分别抑或(抑或了两遍相当于没有抑或)。如果得出来的值比这个数小。就可以#include#include#include#includeusing namespace std;const int MAXN = 110;int a[MAXN];int n;int main()
2016-08-26 20:50:54
914
原创 求sg函数值
题目:hdu1536题意:nim游戏。但是每次拿的数目有限制。解答:dfs求sg值注意:dfs的时候vis数组要重新定义!!!!!#include#include#include#includeusing namespace std;const int MAXN = 10010;const int maxn = 110;int n,m,k,t;int a[maxn]
2016-08-26 20:28:20
650
原创 威佐夫博弈基础2
题目:hdu2177题意:有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。如果你胜,你第1次怎样取子? 解答:如果满足必败态,输出0。否则。首先
2016-08-25 21:03:36
387
原创 威佐夫博弈基础
题目:poj1067题意:游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。先手胜输出1,先手负输出0.解答:有一个神奇的公式。ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,...n 方括号表示取整函数)。在判断是否满足的时候,算出ak与bk的差值
2016-08-25 19:22:54
362
原创 巴什博弈基础2
题目:hdu2149题意:普通巴什博弈。问第一个人要保证自己能赢第一次应该拿多少个,必败则输出none.解答:如果n%(m+1)=0的话必败,如果n >= m,就输出m到n就行。如果不必败。那么第一次那的数目应该等于n%(m+1).为了让对手处于必败态。#include#includeusing namespace std;int main(){ int m,n;
2016-08-25 17:57:10
275
原创 巴什博弈基础
题目:hdu2188题意:两人轮流捐款,每个人最少捐1元最多捐m元。谁先捐到n元谁赢。解答:如果n%(m+1)为0,则后手赢,否则先手赢。#include#includeusing namespace std;int main(){ int T,n,m; scanf("%d",&T); while(T--) { int ok =
2016-08-25 17:21:18
292
原创 堆排序
大体思路:1.一个树用数组存:i为一个结点的下标,则i*2是它的左孩子,i*2+1是它的右孩子。 2.写一个向下调整函数,将i,i*2,i*2+1中较大者调到i,如果本身最大则停止。 3.从n/2处开始向下调整,建立一个大顶堆。 4.建好大顶堆后h[i]则为最大的数,每次将最大的数放在最后n--,然后继续向下调整1。#include#incl
2016-08-24 20:50:05
234
原创 动态建树加深搜之——模仿手机九键输入法
题目:poj1451题意:给你一个词语出现次数的表,然后给你一个输入的数字串,每一步输出它最可能出现的单词。没有了就输出一个东西。解答:建一个字典树,然后深度遍历这课树。每遍历一步都要记录下当前的字符串。最后输出。要记录当前位置最大值。如果该步没有更新过最大值说明这一步找不到字母了。 用一个str数组记录当前的串。用k记录搜到多长了。注意回溯!还有,不管更新不更新答
2016-08-23 19:16:11
1762
原创 给定一个数输出它重复n遍的数
题目:http://codeforces.com/gym/101061/problem/G题意:给定一个数输出它重复n遍的数解答:因为数比较大而且需要模运算,所以可以根据等比数列求和的公式算出。要用到逆元。#include#include#include#include#define ll long long#define mod 1000000007using names
2016-08-21 11:54:27
1211
原创 关于模运算的性质
题目:http://codeforces.com/gym/100792/problem/A题意:在一个b进制的数字系统下。如果x和y(均用b进制表示)的长度相等且组成的数字相同(只是排列不同),那么x和y叫做b-anagram. 一个数k如果叫做b-stable那么对于这个数所有的倍数他们都互相成为b-anagram. 给定一个b求所有的k.解
2016-08-21 10:42:56
1194
原创 最小生成树之——已知一条边求最小生成树
题目:hdu4463题意:已知一条边求最小生成树题解:用kruskal的话,先将该条边连接。再求最小生成树。注意:是双向边!#include#include#include#include#includeusing namespace std;int n;int p,q;bool vis[55][55];struct point{ double x,
2016-08-21 10:37:02
1265
原创 最短路之——寻找每两点之间最短路中的最长路
题目:hdu4460题意:寻找每两点之间最短路中的最长路。若存在某两点不连通,就输出-1.解答:对每个点spfa,然后找最长的边。用邻接链表存~~#include#include#include#include#include#include#includeusing namespace std;const int MAXN = 10010 + 10010;const
2016-08-21 10:18:29
1158
原创 bfs之——寻找多个目的地的最短路
题目:hdu4771题意:寻找带有多个目的地的最短路解答:因为一共最多有4个目的地。所以将四个目的地排序。然后依次求出该顺序的最短路。选择最短的即可。注意:1、下标问题! 2、注意返回误解的情况。#include#include#include#include#include#include#includeconst int MAXN = 1
2016-08-21 10:02:18
932
原创 静态建树之——寻找前缀是否是其他字符串
题目:poj3630题意:寻找前缀是否是其他字符串解答:静态建树! 这个静态的树怎么建立的呢? 1、定义一个结构体作为节点,并且定义节点数组表示这课树上的所有节点。该结构体的一个变量terminal表示该节点是否是一个字符串的最后一个。另一个节点son[10]表示该节点的儿子们的指针。 2、建立一棵树,bo
2016-08-17 14:05:27
369
原创 动态建树之——寻找前缀是否是其他字符串
题目:hdu1671题意:寻找一个号码是否有前缀跟其他的号码一样解答:动态建字典树(在hdu上能过,在poj上不能过)注意:每次加入字符串的时候边加入要边判断!!! 每建完一个树都要释放内存!!!#include#include#include#include#includeusing namespace std;const int son
2016-08-16 21:03:42
417
原创 cf704A——数据结构
题目:CF704A题意:手机里n个应用,q次操作,每个操作三种类型。 type1:将一条x应用的消息加入,标为未读 type2:将x应用的消息全部读一下(包括未读和已读) type3:将所有操作类型为1加入的消息读一下(包括未读和已读)解答:定义一个数组,每次是第一种情况的时候将该类型加入数组。记录每个应用的未读消息数
2016-08-16 10:59:04
449
原创 动态建树之——一个单词是否在其他单词中以前缀的形式存在
题目:poj1056题意:判断一个单词是否在其他单词中以前缀的形式存在解答:建立字典树。在读到单词末尾的时候如果发现它已经有了,就返回false#include#include#include#include#includeusing namespace std;const int sonnum = 3;int ok = 1;struct Trie{ int
2016-08-15 14:38:06
524
原创 动态建树之——出现了几次的单词有几个
题目:poj2945题意:计算出现了1~n次的单词各有几次解答:字典树。建立之后dfs查找注意:mle:树的节点数目定义太大了。因为题目只有ACGT四个字母所以节点数定义为4就足够 map定义啥的不能写在函数外面#include#include#include#include#includeusing namespace std;const i
2016-08-15 14:33:43
364
原创 高精度加减乘除
#include #include #includeusing namespace std;inline int compare(string str1, string str2){ if(str1.size() > str2.size()) //长度长的整数大于长度小的整数 return 1; else if(str1.size() <
2016-08-14 12:59:42
405
原创 二分之——查字典
题目:poj2503题意:查字典解答:二分查找注意:strcmp的用法以及cmp函数的用法#include#include#include#include#include#includeconst int MAX = 100001;typedef struct{ char e[11]; char f[11];}Entry;Entry entry[MAX];
2016-08-14 10:36:28
418
原创 一些位运算
1、 用于整数的奇偶性判断 a & 1 == 1:奇数 2、 判断n是否是2的正整数冪 (!(n&(n-1)) )&& n == 1:是3、 对于正整数的模运算(注意,负数不能这么算)乘2^k众所周知: n。除2^k众所周知: n>>k。mod 2^k:n&((1
2016-08-13 20:15:43
308
原创 stl之——查字典
题目:poj2803题意:查字典解答:map呗注意:gets的用法、sscanf的用法、如何控制空行停止?#include#include#include#include#include#includeusing namespace std;int main(){ map t; char a[25],b[25],s[25]; while(ge
2016-08-12 21:23:35
520
原创 动态建树之——查字典
题目:poj2503题意:给几个单词的意思,再给几个单词,查字典~解答:字典树咯(注意节点定义,每个节点定义一个字符数组)注意:空行停止!!!#include#include#include#includeusing namespace std;const int sonnum = 26,base = 'a';struct Trie{ int num;
2016-08-12 20:46:48
452
原创 动态建树之——寻找最长公共前缀
题目:poj2001题意:寻找最长公共前缀解答:大概是最简单的字典树的建立、查找#include#include#include#include#includeconst int sonnum = 26,base = 'a';char a[10010][26];using namespace std;struct Trie//定义字典树的节点{ int num
2016-08-12 16:07:17
401
原创 扩展欧几里得求逆元
#include#include#include#include#define ll long longconst ll mod = 10007;using namespace std;ll exgcd(ll a,ll b,ll& x,ll& y){ if(b == 0) { x = 1; y = 0; re
2016-08-05 13:46:31
589
原创 大数加减乘除
#include#include#include#include#includeusing namespace std;//compare比较函数:相等返回0,大于返回1,小于返回-1int compare(string str1,string str2){ if(str1.length()>str2.length()) return 1; else if(str
2016-07-15 12:41:51
328
原创 筛素数
#include#include#include#includeusing namespace std;int a[105];int n;void init(){ int m = sqrt(n+0.5); for(int i = 2;i <= m;i++) if(!a[i])//a[i]为质数! { for(int j = i
2016-07-15 12:35:33
273
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅