acm79拦截导弹

这篇博客探讨了拦截导弹问题的解决方法,重点在于寻找数组中的最长严格递减序列。博主分享了如何通过存储有序链表来优化遍历过程,以O(n^2)的时间复杂度找到所有最长序列。此外,还讨论了如何打印最长递减序列,提出了利用递归和额外存储的策略。最后,博主引用了其他博主的思路作为补充。
摘要由CSDN通过智能技术生成

拦截导弹

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 3
描述

某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于等于前一发的高度。某天,雷达捕捉到敌国导弹来袭。由于该系统还在试用阶段,所以只用一套系统,因此有可能不能拦截所有的导弹。

输入
第一行输入测试数据组数N(1<=N<=10)
接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)
接下来行输入导弹依次飞来的高度,所有高度值均是大于0的正整数。
输出
输出最多能拦截的导弹数目
样例输入
2
8
389 207 155 300 299 170 158 65
3
88 34 65
样例输出
6
2
来源
[张洁烽]原创
上传者
张洁烽

这题本身不难,但是在完成之后  我看到了更好的优化思路,整理了下收获不少,特别拿出来分享一下


首先明白题目的本质,题目需要查找一个数组中的最长严格递减序列,最基本的做法也就是对数组进行遍历,   遍历到第i个节点是,向前找比他小的节点,并且存储其中最大的长度加1,如果找不到比他小的,那就存储1,(作为一个新序列的开始)





对于楼主第一个问题 我构想的一个解决方案是在过程中存储的不仅仅是长度为n的序列的最小尾端值,而是挂一个长度为n序列的尾端的有序链表上去,     在最后存pre的时候  存的是长度n  与 对应链表的index,    这样是可以遍历出所有最大长度的序列的,复杂度为 O(n^2)

</pre><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'SimSun';font-size:14pt;"><span style="color:#cc7832;background-color:#344134;">import</span><span style="color:#cc7832;"> </span>java.util.TreeMap<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">import </span>java.util.Scanner<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#629755;">/**
</span><span style="color:#629755;"> * Created by yueguang on 5/18/2015.
</span><span style="color:#629755;"> */
</span><span style="color:#cc7832;">public class </span>anti_missile_imp {

    <span style="color:#cc7832;">public static void </span><span style="color:#ffc66d;">main</span>(String[] args){
        <span style="background-color:#344134;">TreeMap</span><Integer<span style="color:#cc7832;">,</span>Integer>  cacheMap = <span style="color:#cc7832;">new </span><span style="background-color:#344134;">TreeMap</span><Integer<span style="color:#cc7832;">, </span>Integer>()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">       </span>Scanner in  = <span style="color:#cc7832;">new </span>Scanner(System.<span style="color:#9876aa;"><em>in</em></span>)<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">        int</span>[] inputArray  = <span style="color:#cc7832;">new int</span>[<span style="color:#6897bb;">21</span>]<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">        int </span>groups = in.nextInt()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">        while</span>(groups--><span style="color:#6897bb;">0</span>){
            <span style="color:#808080;">//读入数据
</span><span style="color:#808080;">            </span><span style="color:#cc7832;">int </span>missileCount = in.nextInt()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">            for</span>(<span style="color:#cc7832;">int </span>i = <span style="color:#6897bb;">0</span><span style="color:#cc7832;">; </span>i < missileCount <span style="color:#cc7832;">; </span>i++){
                inputArray[i] =  in.nextInt()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">            </span>}
            <span style="color:#808080;">//处理数据
</span><span style="color:#808080;">            </span>cacheMap.clear()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">            </span>cacheMap.put(<span style="color:#6897bb;">1</span><span style="color:#cc7832;">,</span>inputArray[<span style="color:#6897bb;">0</span>])<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">            for</span>(<span style="color:#cc7832;">int </span>i = <span style="color:#6897bb;">1</span><span style="color:#cc7832;">; </span>i < missileCount <span style="color:#cc7832;">;</span>i++){

                <span style="color:#cc7832;">int </span>index= cacheMap.size()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">                int </span>terminal= <span style="color:#6897bb;">0</span><span style="color:#cc7832;">;
</span><span style="color:#cc7832;">                for</span>(<span style="color:#cc7832;">int </span>j = index <span style="color:#cc7832;">; </span>j > <span style="color:#6897bb;">0 </span><span style="color:#cc7832;">; </span>j--){
                    <span style="color:#cc7832;">if</span>(inputArray[i] < cacheMap.get(j)){
                        terminal = j<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">                        break;
</span><span style="color:#cc7832;">                    </span>}
                }

                    <span style="color:#cc7832;">int </span>temp=inputArray[i]<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">                    if</span>(index != cacheMap.size()){
                        temp = temp<cacheMap.get(terminal+<span style="color:#6897bb;">1</span>)?cacheMap.get(index+<span style="color:#6897bb;">1</span>):temp<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">                    </span>}
                    cacheMap.put(terminal+<span style="color:#6897bb;">1</span><span style="color:#cc7832;">,</span>temp)<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">            </span>}
            System.<span style="color:#9876aa;"><em>out</em></span>.println(cacheMap.size())<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">        </span>}
    }

}
 

这种方法相较于上一种方法的优越之处在于离散化了统计数据,  如果输入数列是一个严格不减序列的时候,这种方法也没办法避免O(n^2)的最坏时间,但是针对随机数列,时间复杂度有一个明显的下降,最优情况下为  O(n),如果输入数列是一个严格减序列


另外我们可以打印最长递减序列,这个需要通过额外的存储实现,我们可以针对节点存储preNode,  最后用递归的手段实现打印序列,   如  通过最大长度n  找到   对应的节点索引,递归前序节点,然后打印节点


比较复杂的是打印所有的最长序列,我构想的一个解决方案是在过程中存储的不仅仅是长度为n的序列的最小尾端值,而是挂一个长度为n序列的尾端的有序链表上去, 在最后存pre的时候 存的是长度n 与 对应链表的index, 这样是可以遍历出所有最大长度的序列的,这个我还没实践验证


最后感谢另外一位博主的思路分享  http://blog.csdn.net/joylnwang/article/details/6766317

2015年5月23日13:45:00 抱歉之前 弄错了概念,   TreeMap的键值 才是有序的   现在修正了程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值