叉姐的魔法训练小结(未完结)
2015-11-04 20:17
295 查看
说起叉姐,这是一个让人ym的上古神犇,欣赏了一波叉姐的vj,上面挂的基础魔法训练对我来说每题都是神题。
每天做一两个,做了几天终于做了好几个题了,现在写一下心得。
POJ 2443
这题给你1000个集合,里面有10000个数,然后20W次询问,问你哪两个数有没有在同样的集合中出现。
这题自然就是询问所有集合啊,但是肯定会超时,所以就需要优化
这题用到的是压位优化
用数组记录某个数组是否出现在某个集合中,但是集合1000个需要优化,int可以存31位,于是可以集合的编号/30,这个存数组下标,余数用二进制存为值,然后查询的时候枚举1000/30就可以了,只要两个值与一下就行了Orz
AC代码:http://paste.ubuntu.net/13099921/
POJ 3244
D(Ta, Tb) = max {Ia − Ib, Ja − Jb, Ka − Kb}
− min {Ia − Ib, Ja − Jb, Ka − Kb}
这题是一个元素含有三种属性,然后两个元素之间求一个函数,就是这样子算
首先化简上面的式子D(Ta,Tb)=(|(Ia-Ib)-(Ja-Jb)|+|(Ja-Jb)-(Ka-Kb)|+|(Ia-Ib)-(Ka-Kb)|)/2=(|(Ia-Ja)-(Ib-Jb)|+|(Ja-Ka)-(Jb-Kb)|+|(Ia-Ka)-(Ib-Kb)|)/2
于是可以用三个数组存下每个元素的i-j,i-k,j-k,然后排序,最小的就是减了n-1次,最大的就是加了n-1次,所以这样搞一下,最后除以2就行了
AC代码:http://paste.ubuntu.net/13099949/
POJ 3685
i2 + 100000 × i + j2 -
100000 × j + i × j
这题让你求里面第M小的元素是多少,有5W*5W的元素,所以不可能是穷举,所以需要找一些特点
首先看出来这个元素的值关于i是递增的,可以先二分答案,然后每列二分,找到每列里比它小的数的个数,加起来和m比较,这题还是比较容易的
AC代码:http://paste.ubuntu.net/13099975/
POJ 3213
这题给你三个矩阵,前两个乘积得到第三个,但是第三个里有一个元素错误了,让你找出错在第几行第几列,正确答案是多少
矩阵的乘法是O(n^3)的复杂度,1000阶的显然不能暴力乘,需要一些特殊技巧咯。
首先想到的是只有一个元素出错,就是说这一行的和肯定错误了,其他行的和肯定没错,所以可以在输入第二个矩阵的时候,把每一行的和都求出来,因为第三个矩阵C(1,1)=A(1,1)*Browsum(1)+A(1,2)*Browsum(2)+……+A(1,p)*Browsum(p)
然后就在输入c矩阵的时候判断哪一行错了,然后暴力n^2乘出这行的结果,就行了
AC代码:http://paste.ubuntu.net/13099996/
POJ 3465
这题是说你要和一个黑龙肛正面,然后你可以打他造成一些伤害,你可以用抵挡,抵挡他一次的伤害,还有就是你可以治疗回血
然后问你n回合能打死黑龙么,打死的话最少多少回合,打不死的话最多扣多少血
开头觉得这题好难啊,完全没思路,但是可以这样想
因为要最多扣血,所以可以直接当你每次都攻击黑龙,然后吃他伤害,然后当你被打死的那一下,就找前面黑龙打你最疼的那一下,用格挡或者治疗(如果治疗多余攻击伤害的话用治疗),这里可以用优先队列优化,存起来黑龙的每次伤害,然后每次先打黑龙,再判断你死了没,因为第n回合,如果你打死了黑龙,自己也死了,算你赢
AC代码:http://paste.ubuntu.net/13100019/
POJ 2595
这道题是一个物理模型,p可以看成x坐标,q可以看成y坐标,然后sigma ux=C,sigma u=1,可以看成质心的x坐标为c,然后就是求sigma uy的最大和最小,把n个点的凸包求出来,在凸包上找横坐标为c的时候的质心纵坐标的最大和最小值,就是枚举凸包上的点就行了,这题真是过于机智orz了
可以当作凸包模板,也让我更好的理解了一发凸包
AC代码:http://paste.ubuntu.net/13634290/
POJ 3040
这题就是个贪心,给你一些钱币的面值和数量,然后让你组成大于等于C的钱,能组成几份
这题贪心的思路是,从价值高的开始贪,能放几个就放几个,如果最后没满c,就从最小的能放的放一个就行了,然后对应每种钱币扣掉最多能扣掉的份数,然后重新从大到小贪,这个题是我完全独立做出来的,表示贪心就是需要大胆的走起来
AC代码:http://paste.ubuntu.net/13100497/
POJ 3182
这题就是给你个类似迷宫图的图,然后中间有一块不能走,边上都能走,然后让你从一个起点,绕过中间的那坨东西,再走回来,走最小环
这个感觉好难啊,bfs根本无法解决啊,然后怒看一波题解,题解真是过于厉害了,找中间那坨东西的里面一点,然后往左边或者右边(如果起点和这个线在同一直线上,并且起点在这个选择的点的左边,就往右边射,否则往左边)
然后把这个图就分成了两块,在这个射线上,的每个点,都往上或者往下走,然后不能越过这个线,两边bfs,然后最小和就是答案
AC代码:http://paste.ubuntu.net/13100709/
POJ 3467
给你一个图,然后上面每块都有不同的颜色,然后询问每种颜色的十字架有多少个,十字架就是四个脚一样长的东西,并且要颜色一样,然后就是可以改变某点的颜色,继续询问
这题正解应该挺难,反正我是爆搜水过去的,不造为何这么屌,记录以每个点为中心的十字架个数,再记录总的,每次修改颜色不全部爆搜,这样就能减少不少的不必要情况,水过
AC代码:http://paste.ubuntu.net/13100739/
POJ 3375
这题是给你一些电脑,还有一些接口,每个接口连一个电脑,现在要把每个电脑都连到接口上,然后,要求连完这些电脑之后,用的导线距离最小
题解:这题接口有10W个,数据很大,所以感觉比较复杂,其实这题是dp
dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+abs(a[j]-b[i])),表示前i个电脑连着前j个接口时候的最小花费
但是这样开不下,所以要优化,i那一维用滚动数组优化掉,并且这样10W*2000的枚举还是会TLE,可以发现其实每个电脑只会和他最近的左右各2000个电脑相连,所以其实只需要枚举他的左右2000个,这样就是n^2的复杂度了orz
每次枚举的时候先要比较起点max(i,pos[i]-n-1),终点min(m,pos[i]+n+1);
然后转移的时候要记录前一个的终点,如果枚举的接口序号超过了上一个接口的终点,就需要变成dp[cur^1][pe]+abs(a[i]-b[j]);
最后输出dp[cur^1][pe]就行了
感觉这题好难啊,还是我dp太弱了,dp必须改天来一发
AC代码:http://paste.ubuntu.net/13100819/
POJ 3419
这题真是极为的经典,必须是走一发了
这题求区间内最长连续不重复串的长度
一般区间问题都是线段树啥的来维护,这题是用RMQ
首先预处理出pre[i],表示以i为结尾,到最前面不出现重复的位置,然后把这个信息放进RMQ里,首先我们知道,i递增,pre[i]也是递增的,起码是单调不减的,所以查询的时候,在L-R之间,有些位置结尾的串肯定会走到L外面,就用二分,先找出第一个pre[i]大于l的i,然后这个pos-l,当作一个值,然后用RMQ再查询pos到R的最大值,于是就轻松解决了,我还是太弱了,区间信息的维护和查询,线段树之类的我真是菜狗,必须走起来。鲁大师用离线线段树也轻松怒过,我必须燃烧了
AC代码:http://paste.ubuntu.net/13100846/
每天做一两个,做了几天终于做了好几个题了,现在写一下心得。
POJ 2443
这题给你1000个集合,里面有10000个数,然后20W次询问,问你哪两个数有没有在同样的集合中出现。
这题自然就是询问所有集合啊,但是肯定会超时,所以就需要优化
这题用到的是压位优化
用数组记录某个数组是否出现在某个集合中,但是集合1000个需要优化,int可以存31位,于是可以集合的编号/30,这个存数组下标,余数用二进制存为值,然后查询的时候枚举1000/30就可以了,只要两个值与一下就行了Orz
AC代码:http://paste.ubuntu.net/13099921/
POJ 3244
D(Ta, Tb) = max {Ia − Ib, Ja − Jb, Ka − Kb}
− min {Ia − Ib, Ja − Jb, Ka − Kb}
这题是一个元素含有三种属性,然后两个元素之间求一个函数,就是这样子算
首先化简上面的式子D(Ta,Tb)=(|(Ia-Ib)-(Ja-Jb)|+|(Ja-Jb)-(Ka-Kb)|+|(Ia-Ib)-(Ka-Kb)|)/2=(|(Ia-Ja)-(Ib-Jb)|+|(Ja-Ka)-(Jb-Kb)|+|(Ia-Ka)-(Ib-Kb)|)/2
于是可以用三个数组存下每个元素的i-j,i-k,j-k,然后排序,最小的就是减了n-1次,最大的就是加了n-1次,所以这样搞一下,最后除以2就行了
AC代码:http://paste.ubuntu.net/13099949/
POJ 3685
i2 + 100000 × i + j2 -
100000 × j + i × j
这题让你求里面第M小的元素是多少,有5W*5W的元素,所以不可能是穷举,所以需要找一些特点
首先看出来这个元素的值关于i是递增的,可以先二分答案,然后每列二分,找到每列里比它小的数的个数,加起来和m比较,这题还是比较容易的
AC代码:http://paste.ubuntu.net/13099975/
POJ 3213
这题给你三个矩阵,前两个乘积得到第三个,但是第三个里有一个元素错误了,让你找出错在第几行第几列,正确答案是多少
矩阵的乘法是O(n^3)的复杂度,1000阶的显然不能暴力乘,需要一些特殊技巧咯。
首先想到的是只有一个元素出错,就是说这一行的和肯定错误了,其他行的和肯定没错,所以可以在输入第二个矩阵的时候,把每一行的和都求出来,因为第三个矩阵C(1,1)=A(1,1)*Browsum(1)+A(1,2)*Browsum(2)+……+A(1,p)*Browsum(p)
然后就在输入c矩阵的时候判断哪一行错了,然后暴力n^2乘出这行的结果,就行了
AC代码:http://paste.ubuntu.net/13099996/
POJ 3465
这题是说你要和一个黑龙肛正面,然后你可以打他造成一些伤害,你可以用抵挡,抵挡他一次的伤害,还有就是你可以治疗回血
然后问你n回合能打死黑龙么,打死的话最少多少回合,打不死的话最多扣多少血
开头觉得这题好难啊,完全没思路,但是可以这样想
因为要最多扣血,所以可以直接当你每次都攻击黑龙,然后吃他伤害,然后当你被打死的那一下,就找前面黑龙打你最疼的那一下,用格挡或者治疗(如果治疗多余攻击伤害的话用治疗),这里可以用优先队列优化,存起来黑龙的每次伤害,然后每次先打黑龙,再判断你死了没,因为第n回合,如果你打死了黑龙,自己也死了,算你赢
AC代码:http://paste.ubuntu.net/13100019/
POJ 2595
这道题是一个物理模型,p可以看成x坐标,q可以看成y坐标,然后sigma ux=C,sigma u=1,可以看成质心的x坐标为c,然后就是求sigma uy的最大和最小,把n个点的凸包求出来,在凸包上找横坐标为c的时候的质心纵坐标的最大和最小值,就是枚举凸包上的点就行了,这题真是过于机智orz了
可以当作凸包模板,也让我更好的理解了一发凸包
AC代码:http://paste.ubuntu.net/13634290/
POJ 3040
这题就是个贪心,给你一些钱币的面值和数量,然后让你组成大于等于C的钱,能组成几份
这题贪心的思路是,从价值高的开始贪,能放几个就放几个,如果最后没满c,就从最小的能放的放一个就行了,然后对应每种钱币扣掉最多能扣掉的份数,然后重新从大到小贪,这个题是我完全独立做出来的,表示贪心就是需要大胆的走起来
AC代码:http://paste.ubuntu.net/13100497/
POJ 3182
这题就是给你个类似迷宫图的图,然后中间有一块不能走,边上都能走,然后让你从一个起点,绕过中间的那坨东西,再走回来,走最小环
这个感觉好难啊,bfs根本无法解决啊,然后怒看一波题解,题解真是过于厉害了,找中间那坨东西的里面一点,然后往左边或者右边(如果起点和这个线在同一直线上,并且起点在这个选择的点的左边,就往右边射,否则往左边)
然后把这个图就分成了两块,在这个射线上,的每个点,都往上或者往下走,然后不能越过这个线,两边bfs,然后最小和就是答案
AC代码:http://paste.ubuntu.net/13100709/
POJ 3467
给你一个图,然后上面每块都有不同的颜色,然后询问每种颜色的十字架有多少个,十字架就是四个脚一样长的东西,并且要颜色一样,然后就是可以改变某点的颜色,继续询问
这题正解应该挺难,反正我是爆搜水过去的,不造为何这么屌,记录以每个点为中心的十字架个数,再记录总的,每次修改颜色不全部爆搜,这样就能减少不少的不必要情况,水过
AC代码:http://paste.ubuntu.net/13100739/
POJ 3375
这题是给你一些电脑,还有一些接口,每个接口连一个电脑,现在要把每个电脑都连到接口上,然后,要求连完这些电脑之后,用的导线距离最小
题解:这题接口有10W个,数据很大,所以感觉比较复杂,其实这题是dp
dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+abs(a[j]-b[i])),表示前i个电脑连着前j个接口时候的最小花费
但是这样开不下,所以要优化,i那一维用滚动数组优化掉,并且这样10W*2000的枚举还是会TLE,可以发现其实每个电脑只会和他最近的左右各2000个电脑相连,所以其实只需要枚举他的左右2000个,这样就是n^2的复杂度了orz
每次枚举的时候先要比较起点max(i,pos[i]-n-1),终点min(m,pos[i]+n+1);
然后转移的时候要记录前一个的终点,如果枚举的接口序号超过了上一个接口的终点,就需要变成dp[cur^1][pe]+abs(a[i]-b[j]);
最后输出dp[cur^1][pe]就行了
感觉这题好难啊,还是我dp太弱了,dp必须改天来一发
AC代码:http://paste.ubuntu.net/13100819/
POJ 3419
这题真是极为的经典,必须是走一发了
这题求区间内最长连续不重复串的长度
一般区间问题都是线段树啥的来维护,这题是用RMQ
首先预处理出pre[i],表示以i为结尾,到最前面不出现重复的位置,然后把这个信息放进RMQ里,首先我们知道,i递增,pre[i]也是递增的,起码是单调不减的,所以查询的时候,在L-R之间,有些位置结尾的串肯定会走到L外面,就用二分,先找出第一个pre[i]大于l的i,然后这个pos-l,当作一个值,然后用RMQ再查询pos到R的最大值,于是就轻松解决了,我还是太弱了,区间信息的维护和查询,线段树之类的我真是菜狗,必须走起来。鲁大师用离线线段树也轻松怒过,我必须燃烧了
AC代码:http://paste.ubuntu.net/13100846/
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points