随笔分类 -  HDOJ

摘要:以为是什么复杂的几何题,结果边长是平行于坐标轴的,一下子就变成大水题了。找了半天也没发现题目哪写了边长平行于坐标轴。。。 数据范围小,n次枚举*nlogn排序,暴力枚举就可以过。#include <stdio.h>#include <string.h>#include <algorithm>#define MAXN 1005int n,r;struct pnt{ int x,y;}p[MAXN],p2[MAXN];bool cmpx(const pnt& p1,const pnt& p2){ return p1.x<p2.x;}bool 阅读全文
posted @ 2012-08-27 21:53 Burn_E 阅读(127) 评论(0) 推荐(0)
摘要:水题。虽然求第K大值的方法有很多种,各种树都可以,但这题只要一个元素个数固定的堆就可以了。。。。 #include <stdio.h>#include <string.h>#include <queue>#define MAXN 1000000int n,k,num;char op[5];int main(){//freopen("test.in","r",stdin); while(scanf("%d%d",&n,&k)!=EOF){ std::priority_queue< 阅读全文
posted @ 2012-08-27 21:46 Burn_E 阅读(123) 评论(0) 推荐(0)
摘要:敌人会在图中加一条边,你的任务是摧毁一条边,使敌人所在块不连通,求最小的花费。 首先摧毁双联通分量中的边是没有意义的,这个很容易理解。于是对原图进行缩点,行成一棵树,敌人加某一条边后会形成一个环,摧毁这个环中的点是没有意义的,显然对于敌人来说连接叶子节点形成的环会最大。如果这个环不包含最小边,那么去掉最小边后图就不连通了,所以敌人加边后生成的环必然包括最小边。以这个最小边的两个顶点为根生成两棵树,敌人选取了某个叶子节点后,那么选择从这个叶子节点到根节点路径上的边去摧毁都是毫无意义的。对每个节点维护两个值,一个是以该节点为根节点的子树中最小边权,一个是除去这个包含最小边权的子树外的其它子树... 阅读全文
posted @ 2012-08-27 21:44 Burn_E 阅读(224) 评论(0) 推荐(0)
摘要:一道简单的二分。 #include <string.h>#include <stdio.h>#include <algorithm>#define MAXN 500005int l,n,m;int d[MAXN];int cant(int x){ int now=0,ans=0; for(int i=1;i<=n;i++){ if(d[i]-d[i-1]>x)return 1; if(d[i+1]-d[now]>x)now=i,ans++; } //最后一步要跳到终点 if(now<n)ans++; return ans>m.. 阅读全文
posted @ 2012-08-27 21:13 Burn_E 阅读(154) 评论(0) 推荐(0)
摘要:树形背包的变形,要特殊考虑当用一个机器人遍历一棵子树的情况。 /*d[i][k]表示节点i用k个机器人探索的最小花费跟树型背包问题差不多d[u][k]=d[u][k-i]+d[v][i]+i*w表示给当前已遍历的子树以及父节点k-i个机器人,给当前正在遍历子树i个机器人注意也可以把k个机器人全部给已遍历子树,d[v][0]实际上相当于用一个机器人遍历完再走到父节点所以这种情况下d[u][k]=d[u][k]+d[v][0]+2*w*/#include <stdio.h>#include <string.h>#define MAXN 10005#define MAXK 1 阅读全文
posted @ 2012-08-27 21:09 Burn_E 阅读(144) 评论(0) 推荐(0)
摘要:问小于n的数里n/phi(n)最大的数是多少。 由欧拉函数的性质可得n/phi(n)=n/(n*(1-1/p1)*(1-1/p2)...*(1-1/pn))=1/((1-1/p1)*(1-1/p2)...*(1-1/pn)),其中p1~pn为n的质因数。 可见n的质因数越多,n/phi(n)的值越大,所以令n为连续素数的乘积即可。 #include <string.h>#include <stdio.h>struct bign{ int s[205],len; bign(){memset(s,0,sizeof s);len=1;} bign(char *str){*.. 阅读全文
posted @ 2012-08-27 21:06 Burn_E 阅读(149) 评论(0) 推荐(0)
摘要:简单的类LIS问题,按长和宽排序然后DP。注意两个问题即可,一是要规定长的边为长,短边为宽,二是排序时要将要求较少的块放在后面。 #include <stdio.h>#include <string.h>#include <algorithm>#define MAXN 1005typedef __int64 LL;struct block{ int ai,bi,ci,di; bool operator <(const block& b)const{ if(ai!=b.ai)return ai<b.ai; if(bi!=b.bi)retur 阅读全文
posted @ 2012-08-27 20:51 Burn_E 阅读(175) 评论(0) 推荐(0)
摘要:一道纠结了好久的题,主要是因为一开始思路就想错了,还按着错误的思路想了好久。。。 题目大意就是要找一个最短的字符串,包含所有的合法单词并且不包含所有的非法单词。 题目中给的非法单词非常多,但是合法单词很少,很容易想到用状态压缩来做。我一开始想到的是把每个合法单词当作一个点,然后用哈密顿回路来做,想了半天才发现这个思路明显是错误的。。。。。。 正确的做法是把所有可以作为合法单词结尾的点选出来,BFS出每两点之间的距离,每个点都会有一个压缩状态标记这个点可以作为哪几个单词的结尾,然后DP就可以了。 d[state][v]表示最后一步在v时到达state这个状态需要的最小长度,方程为d[... 阅读全文
posted @ 2012-08-12 02:20 Burn_E 阅读(538) 评论(0) 推荐(0)
摘要:题意是说给你若干个单词,每个单词有一定的分数。如果一个字符串包含了某个单词就会得到该单词的分数,并且可以重复计算。让你输出一个长度不大于N并且分数最大的字符串,分数相等时选最短的,长度相等时选字典序最小的。 DP方程很容易想,就是最普通的自动机DP。麻烦的地方在于保证字典序,如果从上向下DP,要保存前缀,比较字典序每次要从开头开始比较,可以写出来但是比较麻烦。我是将模式串反过来建图的,这样等于从后向前生成字符串,分数相同时每次选择较小的字符就一定能生成字典序最小的字符串,但要注意当两字符相等时要向前比较直到可以分出字典序为止。 代码交上去跑了15ms,看statistic已经排在第五了... 阅读全文
posted @ 2012-08-08 00:26 Burn_E 阅读(517) 评论(2) 推荐(0)
摘要:给出一个DNA串以及若干个带有疾病的串,问至少要改变DNA串中的几个字符,才能让它不携带病毒串。其实还是不包含若干子串的问题,可以转化为走一条不包含病毒串的路径,这条路径组成的串和给出DNA串最少相差几个字符,这样就很容易想到DP方程 d[i][j]一开始初始化为无穷大,x是j的父亲节点,也就是说存在next[x][p]=j,一般都是从前向后刷表的。flag表示这一位和DNA串中的对应字符是否相等,相等时为0,不相等时为1。 注意在走的过程中不要走到危险节点上去。#include <string.h>#include <stdio.h>#define MAXN 1001 阅读全文
posted @ 2012-08-07 15:38 Burn_E 阅读(305) 评论(0) 推荐(0)
摘要:给出M个单词,问长度为N的包含不少于K个单词的字符串一共有多少个。到目前为止做的自动机的题目好像都是差不多样子。。都是包含不包含单词之类的。。 这题用d[i][j][k]表示第i步走到字符j包含了单词集合k,因为一共只有10个单词,可以用二进制压缩状态表示这个集合。注意在建立trie图时要合并节点和它的fail节点的状态,一开始没想到这个WA了一次。状态转移方程为 不加优化的代码交上去时间接近TLE。。。于是改成了滚动数组,并用for循环清0,还是要跑360ms左右。这相对于1s的时限还是很慢的。。。于是点了下Statistic,发现大家都是跑了好几百ms。。。。#include ... 阅读全文
posted @ 2012-08-07 13:15 Burn_E 阅读(207) 评论(0) 推荐(0)
摘要:就是POJ2778的加强版,思路是一样的。 出现过给定的单词的单词数=总单词数-未出现过给定单词的单词数,前者等于26^1+26^2+26^3....26^l,后者等于Mat^1+Mat^2+..Mat^l,这里的Mat是根据能走的字符之间的路径数建立出来的邻接矩阵。两者求出来一减就可以了,对2^64取模可以忽略,直接用unsigned long long做,忽视溢出就等于取模了,注意减法最后结果可能小于0,要加2^64变成正数。 求a^1+..a^n用一次二分就可以,建议这种二分都写成非递归的,效率比较高而且不会有爆栈的隐患。 #include <stdio.h>#include 阅读全文
posted @ 2012-08-07 10:04 Burn_E 阅读(245) 评论(0) 推荐(0)
摘要:AC自动机的模版题,应该是很多人的AC自动机处女作吧。。 在斌牛的讲解下,总算是对AC自动机了解了个大概,这里采用了AC自动机和Trie图两种写法,据说后者在AC自动机DP中用的比较多,应该很快就会做到了。。。两者差不多,Trie图利用失败指针来建图,据说AC自动机到Trie图就是转化成了确定性有穷自动机。 贴一下两种写法的代码,当模版了。 AC自动机:#include <string.h>#include <stdio.h>#include <queue>#define MAXS 500010int cas,n;char s[55],find[100000 阅读全文
posted @ 2012-08-05 00:11 Burn_E 阅读(199) 评论(0) 推荐(0)
摘要:这道题目很有意思,要求简化债务关系。一开始感觉很复杂,稍加分析后发现其实就是简化这个图,让这个图每个点出度为0或者入度为0,也就是说让欠账的人直接掏钱给差钱的人就行了。所以只要读一遍数据,看一下欠钱的一共欠了多少就可以了。 1 #include<cstdio> 2 #include<string.h> 3 using namespace std; 4 int cas = 1, n, deg[1005]; 5 int main() 6 { 7 while(scanf("%d", &n), n) 8 { 9 int ans0 = 0, ans1 阅读全文
posted @ 2012-08-01 01:26 Burn_E 阅读(260) 评论(0) 推荐(0)