[USACO] OPEN11 Bronze Division

PROBLEM 11: bfire

题目说了一大堆,其实抽象成编程问题就是:给定N个数1~n放在编号为1~n的位置上,现在进行移动使得n1放到n2的位置上,n2放到n4的位置上,nk放到n2k的位置上,如果n2k越界则从位置1接着计数,依次类推,问哪个数会出现在1号位置或者哪个数其将要放的位置上的数是已经被移动过的了?举例来说:

1 2 3 -> 2

1 2 3 4 -> 4

1 2 3 4 5 -> 3

1 2 3 4 5 6 -> 4

解法其实很简单,模拟一下数字的移动过程就行了,边界条件就是上述的那两个停止条件。

 


 

 


 

注意注释部分,为了方便,我的数组下标是从1开始的,这样所有2的k次幂,比如128,求得的结果为0,其实应该是128,所以不应该取模,直接减去一个n就可以了。

 

<------------------------------------------------------------------------潇洒的分割线------------------------------------------------------------------------------------------->

 

PROBLEM 12: ssort

有点像快排,非常清晰的递归求解,测试全过,爽!

 


 

 


 

<------------------------------------------------------------------------幽怨的分割线------------------------------------------------------------------------------------------->

 

PROBLEM 13: space3d

看了一下分析,提到了一个Flood Fill算法,上网搜了搜,写了一个递归的解决方案,结果segmentation fault。。。

想了一下应该是栈溢出了,递归的层次太深了

参考这篇文章《Flood-Fill 种子填充》 

 

继续优化,参考了这篇文章《种子填充的优化》

也没怎么仔细看,就看个思路,利用队列解决递归的低效,下面是代码

怎么说呢,首先程序写的相当烂!那六个if语句真是烂透了!!看看别人的程序就知道了。。。(这个以后会改进

其次,让我耗了半个下午的地方就是内存分配超出限制,queue数组和visit数组都声明为int类型时,程序超出内存限制

看了别人的解法尝试着把这两个数组声明为char类型,就过了,无语。。。

char visit -> 15636KB

char queue -> 9784KB

char both -> 6852KB

 

 

 

<------------------------------------------------------------------------蛋疼的分割线------------------------------------------------------------------------------------------->

 

PROBLEM 14: stringe

题目很简单,不过竟然segmentation fault!!原来定义缓冲区长度定义小了,比如

0 9 CHESS这个数据,其实执行玩之后应该有2的9次幂个CHESS,所以需要修正宏定义:

#define MAX_LEN LEN * 12 改成

#define MAX_LEN LEN * 1<<12

最大的开销是需要分配两个400多K的静态数组。。。

下面是程序

 


 

 


 

结果你妹的超时了!继续优化,去掉结构体,串长赋值给一个变量,两个缓冲区交替输出结果,避免不必要的字符串拷贝,很像图像处理中的后备缓冲区的用法。。。

 

 


此题再一次印证了“程序不是调试出来的”这一警句,写程序时就应该注意到空间分配,程序效率等问题,良好的设计才能产出良好的结果,程序就是要追求简单,高效,像你前一个程序,冗余的字符串拷贝难道不需要时间吗?擦!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章