CSU - 2147 疯狂的企鹅

CSU - 2147 疯狂的企鹅

Description
在鹅厂工作的DJ开始训练起了鹅厂的企鹅们,现在DJ教小企鹅玩一个疯狂的游戏(危险游戏,小朋友请勿模仿)。
现在有一排小企鹅,从左到右编号为1….N,每个小企鹅有一个数字,每天早上,如果一个小企鹅发现他右边的小企鹅的数字比他的小,他就会消灭这个小企鹅。问到了第几天才会没有小企鹅可以被消灭,你需要输出天数-1的值
注:所有小企鹅的数字是1…N的排列

Input
每组数据输入格式如下:

第一行一个整数N (N<=10^6)

第二行N个整数,表示1…N号小企鹅的数字

Output
每组数据一行,每行一个整数表示输出天数-1的值

Sample Input
4
4 2 1 3
Sample Output
2
Hint
对于第一组数据:

DAY1:6 2 3 4 5

DAY2:6 3 4 5

DAY3:6 4 5

DAY4:6 5

DAY5:6

对于第二组数据:

DAY1:6 3 5

DAY2:6 5

DAY3:6

对于第三组数据:

DAY1:6

Source
Author
Wells

直接看代码吧

#include <iostream>
#include <cmath>
using namespace std;
const int maxn = 1e6 + 5;
int n;
int a[maxn],b[maxn];//数组a保存小企鹅序列,数组b保存其下标 
int main(){
    while(~scanf("%d",&n)){
        for(int i = 1 ; i <= n ; ++i){
            scanf("%d",a+i);
        }
        int x = a[1];
        b[0] = b[1] = 1;
//      b数组,从数组a的第一个数开始,遇到比这个数大的数,就把该数的下标存到b中
//      并更新与后面的数比较的那个数 
//      这个就能实现在数组a中一段一段的查找更新 
//      b[0]保存数组b存的下标个数 

        for(int i = 2 ; i <= n ; ++i){
            if(x < a[i]){
                x = a[i];
                b[++b[0]] = i;
            }
        }
        b[++b[0]] = n+1;
//      因为我们也要查找a数组中最后一个x后面的序列,所以b数组保存的最后一个下标就是n+1 
//      因此,到此时数组b是存了数组a的第一个数的下标,中间存出现比前面的数(不是指前一个数)
//      大的数的下标,最后一个数存a数组的最后一个数的下标 
        int ans = 0;
        //从b数组的第一个保存的下标开始,往后面一段一段的搜索,所以应该是搜索(b[0]-1)次 
        for(int i = 1 ; i < b[0] ; ++i){
            //于是,x是a[b[i]] k 保存此段的搜索结果 
            x = a[b[i]];
            int k = 0;
            //搜素该段序列,下标从b[i]+1到b[i+1]结束 
            for(int j = b[i] + 1 ; j < b[i+1] ; ++j ){
//              如果下面的两个if都没有进入,就
//              说明其实在数组b保存的这段序列中,满足单调递减哦哦哦~~~~~ 
                k++;
                ans = max(ans , k);
                if(x < a[j]){
//              what?觉得这里没有意义啊,根本进不来 
//              是进得来的,只是在没有进入下一个if之前不会进入这个if,
//              因为下一个if中x更新啦
//              ^__^**^__^嘻嘻嘻 
//              不过,虽然可以进来,但是这段代码意义是什么呢,我注释掉了提交也AC
//              所以还是觉得这个代码没有意义嚯哈哈 
                    ans = max(ans,k);
                    x = a[j];
                    k = 0;
                    continue;
                }
//              前面存下来的a[b[i]]企鹅不用去吃这段序列的所有企鹅
//              因为即将出现该段序列内也有企鹅可以内部吃企鹅啦啦啦啦
//              此时更新x和k,序列的规模也可以理解为变小了,哈哈哈
                if(a[j] > a[j+1]){
                    x = a[j];
                    k = 0;
                }
            }

        }
        printf("%d\n",ans);
    }

    return 0;
}
/**********************************************************************
    Problem: 2147
    User: MM390117
    Language: C++
    Result: AC
    Time:300 ms
    Memory:9836 kb
**********************************************************************/

猜你喜欢

转载自blog.csdn.net/Love_Yourself_LQM/article/details/81836893