随笔分类 - HDOJ
摘要:求X^Z+Y^Z+XYZ=K有多少正整数解。 对于Z=2时是完全平方数可以直接求解,Z=3~31时直接暴力枚举即可,对于所有的X^Y可以全部预处理出来,最多大概也就50000*31种组合。 其实确定了X和Z后,Y可以二分求解的,但当Z>=3时Y能取的值加起来也没有多少。。所以枚举就OK了。 1 #include <stdio.h> 2 #include <math.h> 3 #define MAXN 47000 4 typedef long long LL; 5 const LL INF=(1LL<<31); 6 LL p[47000][31],k;
阅读全文
摘要:给出N个点,第一个点是裁判,其他N-1个点需要裁判过去回答问题,每个点需要的时间不一样,而每个裁判最多能回答M分钟的问题。题目分两问,第一问是如何分配可以使使用的裁判数最少,第二问是如何分配裁判,使裁判走过的总路程和最少,裁判一开始都在1,最终也要回到1。 至于第一问,用一个状态标记已经回答过的人,并用两个数组存回答这些人问题需要的最小裁判数以及裁判数最少时最后一个裁判的剩余时间,然后用类似哈密顿回路形式DP求解就可以了。 第二问,是MTSP(多旅行商)问题,先求出裁判走过每个集合最终回到起点所需走的路程,然后DP合并环即可。比如1~3三个点,裁判在1,那答案就是Min(1->2->
阅读全文
摘要:平面图网络流,比赛的时候想不到怎么建对偶图试了试dinic,居然水过去了。。数据是真水。。 赛后看了各牛的解题报告,才搞懂怎么建对偶图,确实是很巧妙。关于对偶图的概念,可以去看08年周东的论文《两极相通——浅析最大—最小定理在信息学竞赛中的应用》。 建对偶图的难点在于确定每条边相邻的是哪两个块,过程可分为四步 1、将无向图的每条边拆为两条有向边,然后扫描所有的点,将某边对于该点的入边ID和出边ID以及极角存起来。注意起点和终点之间也要连一条边。 2、将与该点相连的边按照极角排序,每条边的入边ID的next指向下一条边的出边ID。不难发现,这样操作以后,每个块周围的边形成了一个环,并...
阅读全文
摘要:网赛第一个看的就是这题,直接打表找规律。很容易发现是由大于4的的偶数以及奇数的平方,再除去偶数的平方所组成。一开始犯了个比较2的错误,要不然应该是FB了。。 也没有去推为什么是这样,这种题目一般都是先打表找下规律,一发现规律就懒的去推了。。 直接sqrt是有精度问题的,但是G++能A,C++是WA,比较简单的办法是sqrt后再通过乘法调整一下。 1 #include <string.h> 2 #include <stdio.h> 3 #include <math.h> 4 typedef long long LL; 5 int cas; 6 LL l,r;
阅读全文
摘要:8进制转10进制,只是对应位的数不一样。 1 #include <string.h> 2 #include <stdio.h> 3 int n; 4 int d[]={0,1,2,0,3,4,5,6,0,7}; 5 int main(){ 6 while(scanf("%d",&n),n){ 7 int sum=0,b=1,nn=n; 8 while(n)sum+=d[n%10]*b,b*=8,n/=10; 9 printf("%d: %d\n",nn,sum);10 }11 return 0;12 }
阅读全文
摘要:给出M个短串,这些短串由前N个大写字母组成。然后随机的按字符生成字符串,每次生成1~N个字符的概率是相等的,当生成串包含任意一个指定短串时,就停止生成。问生成串的长度的期望是多少。 首先建立Trie图,对每个可能作为短串结束的点都打上标记。用E(x)表示从这个点走到停止生成所需长度的期望。显然,对于打标记的点,E(x)=0。对于没打标记的点E(x)=∑(E(next[x][i])*1/N)+1(0<i<N),next[x][i]是它在trie图中接受字母i后走到的点。 然后根据Trie图建立方程组,用高斯消元求解E(0)即可。 高斯消元的精度着实很低,现在的代码能过G++,但C++
阅读全文
摘要:求从L~R转换成B进制之后数位之和为M的数有多少个。 国家集训队09年的论文《浅谈数位类统计问题》对这一类的问题总结的比较详细,数形结合的思想十分巧妙。 第二种查询要用到第一种查询的结果,然后二分一下就可以了。 1 #include <string.h> 2 #include <stdio.h> 3 #include <string.h> 4 typedef long long LL; 5 int q,x,y,b,m,k; 6 int d[32][301],num[32]; 7 int dp(int l,int s){ 8 if(s<0)return
阅读全文
摘要:很黄很暴力的枚举,加上了状态压缩的优化。 用15位的状态压缩木棍,1代表使用,0代表没有使用。然后枚举1~2^15作为一根木棍的组成,取反后的状态为令两根木棍,再枚举这个状态的所有子集,即将它拆成两根木棍。。。然后HASH一下就可以了。 其实是有重复状态的,每种状态都会重复六次。加上一个优化if(len[i]>=len[ii])continue;当第一条边比剩余两条边的和都大的时候就不去枚举剩余两条边的组合,这样效率会高上很多。 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm&
阅读全文
摘要:把1~N的路径处理出来,算出需要的时间,如果时间不够就直接挂了,时间多的话就可以去用这些时间去拿别的物品了。 对1~N这条路径上的所有点做一遍树形背包,注意背包时不要背到这条路径上的点,否则就重复计算了。最后再将路径上的点用背包合并即可。 不过我这么写效率好像比较慢,跑了150ms+ ,rank上有不少0ms的,应该是有更好的算法。。 1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 105 4 struct edge{ 5 int v,w,n; 6 }e[MAXN*2]; 7 int first[MAX
阅读全文
摘要:用一个最小值和最大值来表示每个节点的范围,DFS一遍即可。父亲节点的最小值必然比儿子节点的最小值之和大1(它自身至少要1元),至于最大值,没有什么限制,我一开始一直WA在这里了,因为儿子最大值的和是限制不了父亲节点的,因为父亲节点可以取任意大的值。。最后每个节点的最小值都一定小于等于最大值才会是正确的。。 1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 10005 4 typedef long long LL; 5 const LL INF=100000000000LL; 6 struct edge{
阅读全文
摘要:几何模版题。三维凸包+多边形重心+点面距离。模版一拼就过了。 纯模版这种东西就不贴了。。。
阅读全文
摘要:之前贪心的想法确实是错误的,比赛的时候数据太水了,过了也就没有想那么多了。如果误导了他人,实在是抱歉。 对于每个元素,最坏情况下它只能够到它后面的第9个数字,因为最坏情况下,它后面的四个数字能被它前面的四个数字消掉,这样它就能和原来是它后面的第9个元素相消了,于是我们可以用d[i][st]表示第i个数字,从i开始的10个数字的状态为st时是否可消。之后记忆化搜索即可。 状态转移比较简单,如果st的第1位为0,说明这一位已经被消掉,d[i][st]=dp(i+1,next(st))。如果第1为为1,向后连续找至多五个为1的位,比较是否和第一位数字相同,如果相同,就将st的这两位置为0,然...
阅读全文
摘要:这么水的一道最短编辑距离DP,比赛的时候居然没有去做。。 很裸的最短编辑距离DP,就是要注意环的问题。因为如果直接copy两遍的话,有可能会将本来是同一个位置的字母使用两次。但是可以发现串的长度只有10,最大的编辑距离不会超过10,当原串长度>2*L时环就没有影响了,因为这时如果环中一个字母被使用两次,那最短编辑距离肯定已经大于L了。 我是长度小于20时暴力枚举,大于30时在原串后面copy原创的前20个字符。 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #de
阅读全文
摘要:就是一道比较麻烦的模拟题,比赛的时候没有敲,赛后1A了。。 其实主要是输入比较麻烦,买东西合成物品什么的暴力一点也不会出错的。 代码写的后丑,A了之后也懒的改了。。 1 #include <string.h> 2 #include <stdio.h> 3 #include <string> 4 #include <sstream> 5 #include <iostream> 6 using namespace std; 7 struct equip{ 8 string name; 9 int val,type; 10 string m
阅读全文
摘要:贪心,用set水过。 先按x,后按y排序,都想等时Bob放前面。然后扫一遍遇到Bob就将卡片的y值放入set中,遇到Alice就在集合中找一个能被他覆盖的y最大的数,将它擦去。因为如若能覆盖而不去覆盖了就等于浪费了这个,所以必然选择用掉这张卡片。最后统计一共成功覆盖了多少个即可。 1 #include <string.h> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <set> 5 #define inset multiset<int,greater<int> &
阅读全文
摘要:根据%k=a中a和k的不同组合建立55棵树状数组,每次修改操作只对其中1棵树状数组进行操作,每次查询对其中10棵树状数组统计增量和。 1 #include <string.h> 2 #include <stdio.h> 3 #define MAXN 50005 4 int n,q,x[MAXN]; 5 int ta,tb,cc,k,op; 6 int c[55][MAXN]; 7 inline void update(int *c,int x,int d){while(x<=n)c[x]+=d,x+=x&-x;} 8 inline int query(in
阅读全文
摘要:题目问用1*2组成如图h*w矩形的方案有多少种。 明显的状态压缩DP,从上向下填充,假设两行的状态为stat1和stat2,则需要满足的条件是stat1|sta2=1<<w-1以及stat1&stat2中连续的1都是偶数个。因为上一行为空的下一行必须放一个竖的,而除去竖着到上一行的都是横着的,每一个横着的占的宽度都是2,所以stat1&stat2中连续的1肯定是偶数个。 对每一层要记录一个状态是否搜过,并记录这个状态有多少种方法,即记忆化搜索。复杂度是O(h*(2^w)*(2^w))。 斌牛的方法更为高效简洁,状态表示的是当前轮廓线的状态,复杂度是O(h*w*(2^
阅读全文
摘要:KD树,来源计算几何,在《计算几何-算法与应用》一书中有详细的解释。 这题是比较裸的KD树模型,要在点集中找到离一个点最近的一个点。其实KD树就是一棵多维平衡二叉树,将多维空间分成很多个部分,查找时能够较快的逼近查找点,从而快速的找到距离某点最近或者较近的点。 在网上找到了这份模版,简洁高效。 MARK一下URAL1369,也是一道KD树,目前TLE中。。。 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #define MAXN 100005 5 #define INF
阅读全文
摘要:看了大牛的代码,在斌牛的指导下,终于AC了这题。 题目很短,就是问一个由大写字母组成的矩阵中有多少个不同的子矩阵。 从1到m枚举宽度,对每个宽度进行HASH,hash[i][j]表示s[i][j...j+width-1]这个串的hash值,然后再将hash值按照hash[i][0],hash[i+1][0]..hash[n-1][0],#,hash[i][1]...hash[n-1][1],这样竖着的顺序连接起来。并在每一列的串之间用一个符号隔开,这样形成了一个串,再求这个串的不重复子串有多少个,最后将所有宽度的不重复子串和加起来就可以了。这个应该比较容易理解,当枚举宽度为width时...
阅读全文
摘要:Continuous Same Game (2)是个很BT的搜索,这题是为了做(2)才来做一下的。其实直接模拟很easy的,纯属无聊写了个位运算版本的,感觉效率似乎差不多。。就是用3位表示每一位的状态,这样一个longlong就可以存下一列的状态。 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 typedef long long LL; 5 LL d[22],nfull[22],full[22]; 6 int di[]={-1,1,0,0},dj[]={0,0,1,-1}
阅读全文
浙公网安备 33010602011771号