ACM入门
文章平均质量分 50
ycjpz
菜鸟慢慢进步
展开
-
线性复杂度反转单向链表
假设这是需要反转的链表,那么基本思路就是每次都把大一些的一个放到头指针的后面即第一次把2放到1的前面,这个可以通过把1的next指向3,2的next指向1,再把头节点的next指向2这样就得到了head---2---1---3---4然后再把一下个大一点的数这样操作,即为把3放到头指针后面,把1的next指向4,把3的next指向2,把head的next指向3这些操作只需要利用一些原创 2015-09-24 20:29:02 · 1259 阅读 · 0 评论 -
HDU2.2.3 汉诺塔VII
这道题卡了我好几天,不过最后还是想出来了,我用的是迭代的方法,效率上要比网上查到的递归DFS要高一些,但是却不如那种方法直观。现在我把两种方法都放上来好了。基本思路都是一样的:先自己在草稿纸上画画汉诺塔的移动方法,然后再找规律。我们可以发现,对于N个盘子,最开始是在A柱上,然后之前离散课上分析所需步骤数的时候是转化成较小的子问题,即把N-1个盘子通过某种方法移动到B柱上,然后再把第N个原创 2015-08-19 22:21:18 · 637 阅读 · 0 评论 -
HDU2.3.4 How Many Trees?
其实就是给定顶点数,求二叉树的数目可以这样想:先确定一个根,那么它的左子树为0个顶点时,右子树有n-1个顶点,并且还是二叉树,这就把问题的规模缩小了同理,左子树有1个顶点时,右子树有n-2个顶点所以假设f(n)为n个顶点对应的二叉树的数目,那么可以容易得到递推公式:f(n)=f(0)*f(n-1)+f(1)*f(n-2)+...+f(n-1)*f(0)这就是一个很露骨的卡特兰数原创 2015-09-08 21:06:51 · 409 阅读 · 0 评论 -
HDU2.2.8 Big Number
感觉自己脑子还是太僵了,上一题是大卡特兰数,用到了高精度,这题看到又是大数阶乘,所以想都没想就套了高精度模板,然后自己写了一个输出数字位数的函数,这里还要注意大数模板里的len是指高精度里的数组的程度,但是数组的每个单元最多是可以存放四个数字的,所以最后的那个单元要特殊考虑。但是后来Runtime Error(ACCESS_VIOLATION)了很多次以后才发现n的范围是给到了10的7次方,那原创 2015-09-08 11:20:27 · 469 阅读 · 0 评论 -
HDU2.3.3 Hat's Fibonacci
算是一道水题把(虽然我还是WA了很多次)还是高精度,但这次的数据范围有点大,都已经有两千多位数了,用每个单元放4位数字,貌似后来试了一下还是可以放得下,也是能AC的我刚开始怕不够,就用每个单元放8位数字,就是把高精度模板里的DLEN改成8 但是刚开始忘了把相应的MAXN改成99999999,所以WA了每个单元存放8位数字,用a[256]就足够了,然后因为最多2005位,则最大的数也原创 2015-09-08 20:25:41 · 473 阅读 · 0 评论 -
HDU1.3.5 Saving HDU
刚开始看描述还以为是背包,看到后面可分割才明白是最简单的排序···代码如下:#include #include #include using namespace std;struct thing{ int p; int volume;}t[110];bool com(thing a,thing b){ return a.p>b.p;}int main(){原创 2015-08-05 18:27:14 · 438 阅读 · 0 评论 -
HDU1.3.4 开门人和关门人
就用string类型排一下序就好了而且string类型比较方便的是可以直接比较大小而不需要使用strcmp顺便吐槽一句为什么HDU的提交选择C++就不能识别cin>>导致CE,换成G++以后就AC了代码如下:#include #include #include #include using namespace std;struct person{ string ID;原创 2015-08-05 16:46:33 · 505 阅读 · 0 评论 -
HDU1.3.6 Rank
遍历一遍记录比他分数高的人即可这题学到了点新东西,就是这种不提前给test case的个数的题目以前只会根据scanf()!=EOF来判断,这次为了用cin读入字符串,cin读入后返回的是字符流,如果读入失败本身就会返回false因此只需要用一个while(cin>>x)来判断给的输入文件是否结束即可代码如下:#include #include #include usin原创 2015-08-05 18:51:46 · 358 阅读 · 0 评论 -
HDU1.3.7 Crixalis's Equipment
最开始没想清楚,就直接根据物品的B来排序,想着把B大的物体先放入,但是WA了后来自己想了一个例子,比如V有11,然后物品1是10 11,物品2是1 1,此时要先放1但是当物品1是10 10,物品2是1 3时,要先放物品2于是想到了根据B与A的差来排序,因为当B与A相同时肯定是放在最后放的,因为不需要去“照顾”这种类型的物品B与A差值越大的越需要先放还有一种比较科学的分析原创 2015-08-06 14:43:10 · 453 阅读 · 0 评论 -
HDU2.2.4 Wolf and Rabbit
和之前有一题一样,那题是很多人坐成一个圈,然后每隔几个人报数,原理相同,即为m与n互质即可全部遍历。代码如下:#include #include using namespace std;unsigned long gcd(unsigned long a,unsigned long b){ if(a<b){ unsigned long temp=a; a=原创 2015-08-19 23:11:56 · 436 阅读 · 0 评论 -
HDU2.1.1 最小公倍数
求两个数a,b的最小公倍数的方法:先求出a与b的最大公约数c,然后再用a与b的乘积除以c即可得到最小公倍数最小公倍数则用欧几里得算法即可代码如下:#include #include #include using namespace std;int gcd(int a,int b){ if(a<b){ int temp=a; a=b; b=temp; }原创 2015-08-07 10:03:29 · 589 阅读 · 0 评论 -
PAT1067 Sort with Swap(0,*)
就是要用一种独特的排序方式来把数列排序这种排序方式是:只能交换0与其他的数最直接的想法当然是把0和它所在位置的应该是什么数交换,比如0在a[3],那么当然是找到3然后与0交换,这样3就换到了正确的位置如果0已经在a[0],那么就把它和数列中从左往右扫描的第一个没有在正确位置的数交换这个思路是很容易想到的,但是不优化的话就会超时一种比较简单的优化方法就是从左往右扫描,记下遇到的第原创 2015-10-21 17:20:17 · 420 阅读 · 0 评论 -
HDU2.3.1 A + B Problem II
依旧是用大数模板,但是我很作死的自己改了一下模板,把输出大数里的“cout结果就WA了三次,然后用9999与1检查发现只输出了10而不是10000,但是让它输出长度的话还是2是没有错的,只是后面那4个0只输出了一个然后回过头去检查才发现cout还是很强大的,因为用了cout.width(4)与cout.fill('0')使程序能够保证就算原来某个单元(最后一个单元除外)里存的如果不到4位也原创 2015-09-08 16:00:44 · 480 阅读 · 0 评论 -
O(N^3)找最大子矩阵Submatrix
其实这个方法是从找最大子序列演化过来的找最大子序列的话,最直接的方法是确定左右边界,然后把这之间的加起来,与当前最大值比较,这样做法复杂度为O(N^3)稍微优化一下的话,是确定一边,然后一个一个加上去,每次与当前最大值比较,这样做法复杂度为O(N^2)再优化一下,就是从第一个开始加,每加一次之后与当前最大值比较,一旦和小于0,就把和清零,因为说明前面的那段对最大没有贡献,复杂度为O(N原创 2015-09-26 22:44:44 · 2375 阅读 · 0 评论 -
HDU2.2.7 Train Problem II
就是一个卡特兰数的问题,而且出题者比较坏,数据给的很大,所以必须用C++的高精度,或者直接用JAVA自带的BigInteger类型,但由于自己用不来java,所以只好用高精度了。关于卡特兰数,有以下递推:令h(0)=1,h(1)=1,catalan数满足递推式:h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)例如:h(2原创 2015-09-07 22:50:28 · 613 阅读 · 0 评论 -
HDU2.1.8 小数化分数2
分成三种情况来讨论:(1)只有普通小数(2)只有循环小数(3)前面是普通小数,后面跟着循环小数把普通小数的位数num和循环小数位数(即为括号中的数字个数)cir_num统计出来对于情况(1),就是把小数表示的数字除以对应的10的次方,比如0.32对应32/(10^2)对于情况(2),就是把小数表示的数字除以对应的10的次方减1,比如0.(32)对应32/(10^2-1)原创 2015-08-08 18:13:45 · 1346 阅读 · 0 评论 -
HDU2.1.3 相遇周期
为什么感觉是题目出错了···我刚开始的做法是根据所给数据求出两个卫星的各自周期T1和T2然后再用T1*T2/abs(T2-T1)即可但是这样求出来和样例拍不上上网查了一下,(虽然我并不明白原理),是要把原来的分数先化为最简,然后求分子的最小公倍数作为分子,以及分母的最大公约数作为分母,再把它们约分到最简单即可得到结果,但是我仍然认为自己最初的做法是对的···用这个所谓的能AC的原创 2015-08-07 21:15:57 · 1124 阅读 · 3 评论 -
HDU1.3.8 As Easy As A+B
就是排序,输出格式有点蛋疼,必须是每个数之间都有空格,但是最后一个数后不能有空格代码如下:#include #include #include #include using namespace std;int a[1001];int main(){ int T; cin>>T; while(T--){ int N; scanf("%d",&N); for原创 2015-08-07 10:00:42 · 403 阅读 · 0 评论 -
HDU2.1.2 How many prime numbers
就是判断质数,因为数据范围比较小,所以直接用最普通的判断方法即可,也就是枚举比其平方根小的数看看是不是它的因子。如果数据范围很大的话可以用素数的线性筛法,以后应该会碰到。代码如下:#include #include #include #include using namespace std;bool isprime(int x){ for(int i=2;i<=sqrt原创 2015-08-07 10:13:34 · 472 阅读 · 0 评论 -
HDU1.3.3 百步穿杨
唯一需要知道的就是结构体排序吧,自己写一个排序规则即可代码如下:#include #include #include using namespace std;struct arrow{ int l; int num;}a[40];bool com(arrow a,arrow b){ return a.l<b.l;}int main(){ int T; c原创 2015-08-05 16:25:58 · 562 阅读 · 0 评论 -
HDU1.3.2 今年暑假不AC
刚开始不知道怎么做,以为是动态规划之类的后来才发现是贪心即可就是把节目根据结束时间排序,然后选择结束最早的节目,再选择下一个能选择的节目里结束最早的节目,就这样一直选下去即可然后要注意节目可以无缝衔接,即比较的时候是代码如下:#include #include #include #include using namespace std;struct tv{ int原创 2015-08-05 16:14:43 · 403 阅读 · 0 评论 -
HDU1.3.1 FatMouse' Trade
就是贪心,算出每个房间的J/F的比值,然后排序,再按性价比从高到低去取有人提到F可能为0,这种情况也包括在内了,因为F为0时quo即为无穷大,那么必然会去先取那个无穷大性价比的房间。代码如下:#include #include #include #include using namespace std;struct room{ int J; int F; double原创 2015-08-05 09:16:58 · 531 阅读 · 0 评论 -
HDU1.1.1 A+B for Input-Output Practice (I)
就是简单的整数相加,当没有输入的时候退出。很早以前就是通过这题知道了用scanf()!=EOF来检验是否还有输入#include using namespace std;int main(){ int a,b; while(scanf("%d%d",&a,&b)!=EOF){ printf("%d\n",a+b); } return 0; }原创 2015-08-03 20:33:18 · 512 阅读 · 0 评论 -
HDU2.2.6 Digital Roots
刚开始想复杂了,掉进坑里了,而且还用了 这个库来用stream的方法将int类型转化为string类型,但是我总算明白了为什么当年书上叫我们慎用stream了,这速度真是慢的感人,直接让我TLE了这个方法应该是可行的,就是时间方面不允许,这种方法的代码如下:#include #include #include using namespace std;std::strings原创 2015-08-29 22:25:09 · 355 阅读 · 0 评论 -
HDU2.2.5 三角形
这题刚开始觉得好难,在纸上画画感觉没什么规律,后来才发现只要写出前四个就可以找出规律了这个就是需要画图画的细致一点,尤其是四个三角形的时候一个三角形是2、两个三角形是8、三个三角形是20、四个三角形是38它们之间的差是6、12、18 都是6的倍数于是就想到了a[i]=a[i-1]+6*(i-1)后来在网上也看到了另一种解释,虽然也没有证明(也可以看成是找规律吧),就是每种情原创 2015-08-29 20:58:06 · 562 阅读 · 0 评论 -
HDU2.2.2 Joseph
刚开始没有去考虑复杂度,直接很单纯地模拟,然后果然超时了···但是一看到这么少的数据种类(k只有1到13),那么直接打表就好,打表的话妈妈再也不怕我超时了~还是提一句,所谓打表就是提前把所有可能的情况都存在一个数组里,然后根据输入直接输出相应数组中的数即可。其实打表就是把原来会超时的代码利用本地运行来节省时间,单纯拿出结果。这虽然有点流氓,但是还是很实用的一种方法,打表的代码和原创 2015-08-10 22:13:14 · 742 阅读 · 0 评论 -
HDU2.2.1 Fibonacci
这年头数学真的太重要了···第一次遇到这么大的斐波那契数列,用数组递推肯定会被卡掉的后来网上看了看别人的解题报告才想起来斐波那契数列是有递推公式的递推公式的话自行百度好了,这里打起来很麻烦···关键其实还是如何取大数的前四位,其实之前遇到过的那题取N^N的第一位的题是差不多的,但是由于那题没有搞得很清楚,导致这题也卡主了,以后再也不这样了···其实就是如果我们要求一个数的前4位,比原创 2015-08-09 16:32:25 · 685 阅读 · 0 评论 -
HDU2.1.6 The area
又是一道数学题而且刚开始一时疏忽竟然把抛物线方程设成了y=-(x-x1)^2+y1,连a都忘记设了,后来检查时才发现,后面的就很简单了,把抛物线和直线都表示出来然后算一下定积分即可。代码如下:#include #include #include #include using namespace std;double f(double x,double k,double b,原创 2015-08-08 09:10:33 · 539 阅读 · 0 评论 -
HDU2.1.4 Cake
直觉就是这题会有公式,然后和别人一起讨论了很久之后毫无进展后来只好参考了一下别人博客里的想法终于恍然大悟就是把一个圆,在圆周上画点将其等分,想分成p等份需要画p个点想分成q等份需要画q个点并且如果都是从同一个起点开始画,那么会有gcd(p,q)个点是重合的于是公式就是p+q-gcd(p,q)代码如下:#include #include using namespa原创 2015-08-07 22:01:59 · 582 阅读 · 0 评论 -
HDU2.1.7 Leftmost Digit
看到这么大的数据,本来第一反应是高精度,但是感觉10亿的10亿次还是会爆的,于是又想了很久,但是实在想不出,于是只好去其他博客里看看解答。看完了解答真是忍不住拍手喝彩,这就是数学境界的差距。假设M=N^N,那么题目就是要求M的第一位数字,两边求log(10为底数),于是log(10)M=Nlog(10)N,于是M=10^(Nlog(10)N),由于10的整数次方必然是1000···0,最高原创 2015-08-08 17:20:58 · 582 阅读 · 0 评论 -
HDU1.1.2 A+B for Input-Output Practice (II)
就是给定test case的输入求和推荐用while(T--)来控制次数#include using namespace std;int main(){ int i,a,b,N; scanf("%d",&N); while(N--){ scanf("%d%d",&a,&b); printf("%d\n",a+b); } return 0; }原创 2015-08-03 20:35:57 · 453 阅读 · 0 评论 -
HDU1022 Train Problem I
是一道很露骨的模拟栈的题目,但是由于第一次做到,还是卡了一下的。就是用一个stack来模拟,让进栈的序列逐个进栈,然后再每次都判断一下是否与当前出栈序列的位置符合,如果不符合就继续进栈,如果符合就出栈,弄清楚各个的标记即可。因为如果当前的栈顶符合出栈序列的当前位置却不出栈的话,它一定会在接下来入栈的车的后面出栈,就不可能符合给定的出栈顺序。然而题目的数据好弱,后来才发现我都忘了用题目中原创 2015-08-30 20:59:13 · 577 阅读 · 0 评论 -
HDU1.2.8 Lowest Bit
利用位运算判断最后一位是不是1,如果不是的话就把A向右移一位,并把计数器向左移一位(即乘二)#include #include using namespace std;int main(){ int A; scanf("%d",&A); while(A){ int temp=1;; while(!(A&1)){ A>>=1; temp<<=1; }原创 2015-08-04 22:17:49 · 423 阅读 · 0 评论 -
HDU1.2.6 Buildings
简单读入矩阵的同时计数可以用bool类型#include #include #include using namespace std;int main(){ int T; cin>>T; while(T--){ int m,n; bool a[101][101]; scanf("%d%d",&m,&n); int count=0; for(int i=原创 2015-08-04 22:00:16 · 390 阅读 · 0 评论 -
HDU1.2.2 Biker's Trip Odometer
勉强能算作数学题吧···注意单位转换即可#include using namespace std;#define p 3.1415927int main(){ int N=1; while(1){ float d,t; int r; scanf("%f%d%f",&d,&r,&t); if(r==0) return 0; float dis,MPH;原创 2015-08-03 20:40:04 · 539 阅读 · 0 评论 -
HDU1.2.7 Higher Math
勾股定理,注意输出格式即可#include #include #include using namespace std;int main(){ int T; cin>>T; for(int _=1;_<=T;_++){ int a[3]; scanf("%d%d%d",&a[0],&a[1],&a[2]); sort(a,a+3); printf("Scena原创 2015-08-04 22:09:59 · 494 阅读 · 0 评论 -
HDU1.2.5 find your present (2)
这种特别大的数,开一个数组不现实,于是想到用mapHDU不支持bits/stdc++.h让我郁闷了好久,都要一个一个打头文件好麻烦···刚开始还把map定义成全局函数导致WA了后来改成在循环内部就AC了代码如下#include #include #include #include #include using namespace std;int main()原创 2015-08-03 21:26:55 · 524 阅读 · 0 评论 -
HUD1.2.4 Nasty Hacks
又是一道超级水的小学数学题···感觉杭电的这个难度安排有点奇怪呀#include #include #include #include using namespace std;int main(){ int n; cin>>n; while(n--){ int r,e,c; scanf("%d%d%d",&r,&e,&c); if(r>e-c) print原创 2015-08-03 20:45:51 · 440 阅读 · 0 评论 -
HDU1.2.3 hide handkerchief
最开始以为只是一道超级水的模拟题,但是用以下的模拟会超内存限制#include #include #include using namespace std;bool a[100000001];int main(){ int N,M; scanf("%d%d",&N,&M); while(N!=-1&&M!=-1){ int temp=1; memset(a,0,si原创 2015-08-03 20:43:02 · 471 阅读 · 0 评论 -
HDU1.2.1 Elevator
就是简单的模拟电梯的情况即可#include using namespace std;int main(){ while(1){ int i,j=0,temp[2],N; long time=0; scanf("%d",&N); if(N==0) return 0; scanf("%d",&temp[0]); time+=6*temp[0]; time+=5; f原创 2015-08-03 20:37:55 · 619 阅读 · 0 评论