PAT 1001~1017题小结

 

  • 1002. A+B for Polynomials 50min  自制链表归并所以用时多。如果用数组/std::list会快很多

  • 1003. Emergency               很久  读题不够准确。 方法也一般般, dijk+dfs。 实际一次dijk就可以得到

  • 1004. Counting Leaves      30min  遍历多叉树

  • 1005. Spell It Right   9min

  • 1006. Sign In Sign Out   30min

  • 1007. MaxSubsequenceSum   40min 题目描述理解不好。

  • 1008. Elevator     10min 简单题,纯模拟

  • 1009. Product Polynomials 40min 手写链表太慢了,有可能有bug。后来用stl,但是有几个函数用法不熟,emplace 和splice。

  • 1010. Radix      很久 以为是简单题,题目描述太简单了,自己读题又作了太多不必要数据范围假设。
            因为数字是0-9a-z 共36个数字,但是题目没有限制进制的上限。很可能是上万进制的。
            不过题目也没有说清楚数据范围,万一long long都不够用,就歇菜了。
            最后查找进制的时候,线性查找会超时,没想到用二分法。

  • 1011. World Cup Betting   15min 水题,属于阅读理解。不过一个> 和 < 搞错了,浪费不少时间。

  • 1012. The Best Rank    75min 水题,思路很直接,就是排序,不过由于每个学生有四课分数ACME,因此需要排序四次。
            而且还有同分的问题。库函数使用不够熟练, sort lowerbound binary_search 要多看看。

  • 1013. Battle Over Cities  70min 并查集写的不熟练,路径压缩的实现是必备的。

  • 1014. Waiting in Line   很久    队列模拟银行排队,但是大方向有了,写起来诸多不畅。
            而且题意理解有问题,17.00之后不受理新业务,但是17.00前开始的业务还是要做完的

  • 1015. Reversible Primes   40min 质数判断,新增 reversible prime的概念,要进行进制转换后,再逆序。生成10w内质数表直接查表。

  • 1016. Phone Bills    很久  模拟题题意理解很繁杂,而且没有说明,客户没有消费的时候不需要输出账单。资
            费的计算每小时都不同,如果按照day hour minu分段计算的话,会很麻烦。
            最后用了取巧的做法,直接从当月1号0点开始计费,两个资费相减即可。
            顺道练习了stl组合使用。map 。 为了给 char[20]增加 <, 定义一个类str20.
            比较函数的参数和函数的const要记得加上。
     

  • 1017. Queueing at Bank 40min   队列模拟题,有几个地方描述比较模糊。窗口使用时间超过一小时后怎么办? 重新排队还是只算60. 思路还是不够清晰,写起来窒碍颇多。

 

综上:

1. 涉及到时间,排队的题细节很多,准确的阅读理解是个问题,再者写起来大致思路是有的,但是往往有疏漏的情况,导致卡很久。

2. 重要数据结构的实现不熟练,只是知道核心的思路,实现的时候还是要想好久。

3. 有时会想当然的给数据范围增加限制。。例如1010 radix, 看到只有36个数字,就以为最多36进制。

4. stl的各种容器和中的算法使用不熟练,要查资料,还有一堆c++模板的编译报错似乎不是给人看的 (>.<)

 

 

 

 

建立哈夫曼树的小优化

PAT 1001~1017题小结_第1张图片

replaceMin(H, T)  //这个replaceMin 复杂度和删除一样,都是logN
{        
		int i=1, child=2;            
		while ( child <= H->size )   //这里原本是错误的 <。修正为 <=        
		{              
			if ( child!= H->size && H->elements[child] > H->elements[child+1 )   
				child++;                
			if ( H->elements[child] > T )      
				break;                
			H->element[i] = H->element[child];         
		}        
		Elements[i] = T;
}

for(){        
	T = malloc();        
	T->Left = DeleteMin(H);        
	T->right= Top(H);        
	T->wt = T->right->wt + T->left->wt;        
	replaceMin( H, T );
}

 

这样一来for循环体  有三个操作,  deleteMin  Top  replaceMin,  一共两个logN的操作和一个O(1)的操作

 

你可能感兴趣的:(pat甲级,算法题)