HDOJ-ACM 1023-1027 1058解答及思路
1023
Problem Description
Output
Sample Input
Sample Output
题目要求
基于1022题,在它的基础上要求输出小于100辆火车进站后的出站顺序。
参考AC代码(一)
|
|
参考AC代码(二)
|
|
思路
首先,我们假设f(n)是序列个数为n的出栈序列种数。(我们假定,最后出栈的元素为k,k取不同值时的情况是相互独立的,也就是求出每种k最后出栈的情况数后可
用加法原则,由于k最后出栈,因此,在k入栈之前,比k小的值均出栈,此处情况有f(k-1)种,而之后比k大的值入栈,且都在k之前出栈,因此有f(n-k)种方式,由于比k
小和比k大的值入栈出栈情况是相互独立的,此处可用乘法原则,f(n-k)f(k-1)种,求和便是Catalan递归式。而该题要用到Catalan的递归式:h(n)=h(n-1)(4*n-2)/(n+1);
而该题最大求到了h(100),已经超过了50位且接近60位数,所以long long型也无法使用,要使用大数的乘法和除法。代码一是以10为基准教容易理解。而代码二是以
10000为基准,即数组的一个位置可存放四位数,把四位数作为一个整体进行计算。此题的乘除法也设计的极为巧妙,大大减少了运算复杂度。
注意事项
开始需要把h[1]的那一行全部初始化为0,再用memset时确保每一行没有用到的位置全部置为0。在使用10000为基准的时候要注意一次性输出4位数,若不满4位数则要
向左用0补齐。在使用除法运算的时候,若有一位没有除尽,则要把余数*基数加上后一位的数字,继续进行除法运算。若基数取的是10,则进行的是我们熟悉的运算,容易
理解。但相应的也会增加程序的运行时间。
转跳 Catalan number
1024
Problem Description
Input
Output
Sample Input
Sample Output
题目要求
给定n个数,和m个段。求在这n个数中求出m个子段,使得这些子段的和最大.
参考AC代码(一)
|
|
参考AC代码(二)
|
|
思路
见代码注释
代码(二)思路与(一)相同,只是处理的方法略有不同。
注意事项
由于这题给的n很大,需要用dp来解。而且需要优化操作。
1025
Problem Description
Input
Output
Sample Input
Sample Output
题目要求
两条线,每条线上各有n个点,表示n个城市,第一条表示rich 城市,第二天表示poor 城市,从第一条线连接到第二条线上,问最多能连多少条不相交的路线。
参考AC代码
|
|
思路
LIS算法:可以按照富有(贫穷)的排序,然后找贫穷(富有)的村子序列的最长上升子序列就可以了,这样就能保证不相交,而且就是最优解。
注意事项
因为数据大,n^2的算法是不可以的,需要使用n×logn的算法形式。需要注意road有单复数形式。可以发现B插入数据是有序的,而且进行替换而不需要移动,
也就是说可以使用二分查找,时间复杂度就降下来了。这种算法只能得到最终的数据个数,但是如果需要得到具体的内容就不行了。看网上说首先要排序,
其实仔细看看题目的说明,它的边的输入是有序的,所以根本不需要进行排序。
1026
Problem Description
Input
Output
Sample Input
Sample Output
题目要求
迷宫问题。要求从左上走到右下并记录下实时的数据。
参考AC代码
|
|
思路
使用广搜+优化队列可以使得到的第一个路线就是最优化路线。mg数组中.存放的为1,X存放的为-1,怪物需要消耗几秒就存储几秒。flag数组用来存放走过的位置,
若走过的话存储为1,不能再走。使用优化队列,每次进行判断的都是队首的元素,如果满足继续放入队首,继续对改元素进行下一步判断。若不满足则退出队列,
第二个元素再进行判断,依次重复最后得到最优解。再使用栈进行输出。从末尾开始反向把元素一一压入栈中,再利用栈的特点从正向开始输出。pre数组存储的是
每个满足题意的坐标用于输出。
注意事项
flag数组需要初始化为0,输出的时候遇到怪物的情况需要额外讨论。本题若使用深搜会超时,需要使用广搜+优化队列求解。把自己定义的结构体变量放到自己建立的
队列或者栈中时需要重载小于号。
本题使用了queue和stack的头文件:
(1)queue:若定义队列queue q,q.empty()判断是否为空队列,q.push(1)表示元素1进队列,q.pop()表示出队列,q.front()表示得到队首的值,q.size()表示得
到队列里元素个数。
(2)stack:若定义栈stackq,q.empty()判断是否为栈空,q.push(1)表示元素1进栈,q.pop()表示弹出栈中元素,q.top()表示取出栈顶元素,q.size()表示得到栈
中的元素个数。
1027
Problem Description
Input
Output
Sample Input
Sample Output
题目要求
按照字典顺序输出从1-n n个自然数的组合数。
参考AC代码
|
|
思路
本题若使用如上代码的STL全排列函数,则可以快速求解,它的作用就是求出下一个字典序的组合数。与之对应的有prev_permutation,作用是求出上一个字典序
的组合数。但是它并没有真正带给我们实质的知识点,所以下面给出不使用STL的求解方法。
|
|
以上代码的思路为:
从末尾开始判断前一个元素是否小于后一个元素,若找不到向前推动搜寻数组的位置,若能找到,则说明可以找到比改数大的一个组合数。那么再定义j从末尾开始与i-1的大
小,若a[i-1]<a[j],那么交换两数的位置后再交换a[i]与a[n]的数值以确保大数排到了后面,一直执行permutation函数到满足题意。
注意事项
每行的末尾没有空格,所以需要讨论输出格式。
1058
Problem Description
Input
Output
Sample Input
Sample Output
题目要求
定义了一个humble numbe,并找出第N个humble number。定义为:除了1以外仅有2,3,5,7一个或多个因子的数。
参考AC代码
|
|
思路
先用data数组存放1-5842的humble number,接着判断n的末尾用哪种输出格式。data存放humble number的原理为:用这4个因子分别乘1,接着找出最小的数并判断是
属于哪个因子的,之后该因子的乘数+1,若res是一个新数,那么存入data数组,index再指向下一个位置,若index到了5843结束循环。
注意事项
在英语中11,12,13由于有对应的单词,所以不使用st,nd,rd,需要特别注意。另外此题需要用long long来储存数组,由于方便起见,可以用typedef把long long重新
定义为LL,可以节省书写速度。