【NOIP模拟】盘子序列

题面

有 n 个盘子。盘子被生产出来后,被按照某种顺序摞在一起。初始盘堆中如果一个盘子比所有它上面的盘子都大,那么它是安全的,否则它是危险的。称初始盘堆为A,另外有一个开始为空的盘堆 B。为了掩盖失误,生产商会对盘子序列做一些“处理”,每次进行以下操作中的一个:(1)将 A 最上面的盘子放到 B 最上面;(2)将 B 最上面的盘子给你。在得到所有 n 个盘子之后,你需要判断初始盘堆里是否有危险的盘子。

20%的数据保证 n<=8
80%的数据保证 n<=1,000
100%的数据保证 1<=n<=100,000,0<盘子大小<1,000,000,000 且互不相等

分析

可以抽象出其实是个判断是否是合法出栈序列的模型。

O(N2)做法:判断每个数后面比它小的数构成的序列是否递减(显然,一个较大的数被拿出来后,后面的数只能递减)

O(N)做法:维护一个最大值,只需要判断比最大值小的序列是否递减,当更换最大值的时候序列清空。

反正水,瞎搞也行。

代码

分段写了

 

  1. #include<bits/stdc++.h>  
  2. using namespace std;  
  3. #define N 100010  
  4. #define RT register  
  5. int n,ok,cnt,top;  
  6. int a[N],tmp[N];  
  7. template<class T>  
  8. inline void read(T &x)  
  9. {  
  10.     x=0;int f=1;static char ch=getchar();  
  11.     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}  
  12.     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
  13.     x*=f;  
  14. }  
  15.   
  16. int main()  
  17. {  
  18.     while(scanf("%d",&n)==1)  
  19.     {  
  20.         ok=1;  
  21.          for(RT int i=1;i<=n;i++)read(a[i]);  
  22.          if(n<=1000)  
  23.          {  
  24.             for(RT int i=1;i<=n;++i)  
  25.             {  
  26.                 int x=a[i];cnt=0;  
  27.                 for(RT int j=i+1;j<=n;++j)  
  28.                 {  
  29.                     if(a[j]>x)continue;  
  30.                     tmp[++cnt]=a[j];  
  31.                 }tmp[cnt+1]=0;  
  32.                 for(RT int i=2;i<=cnt;++i)  
  33.                 {  
  34.                     if(tmp[i-1]>tmp[i]&&tmp[i]>tmp[i+1])continue;  
  35.                     else {ok=0;break;}  
  36.                 }  
  37.                 if(ok==0)break;   
  38.             }  
  39.             if(ok)printf("Y\n");  
  40.             else printf("J\n");  
  41.          }  
  42.          else  
  43.          {  
  44.             top=0;  
  45.             for(RT int i=1;i<=n;++i)  
  46.             {  
  47.                 if(a[i]>top)cnt=0,top=a[i];  
  48.                 else  
  49.                 {  
  50.                     if(cnt==0||tmp[cnt]>a[i])tmp[++cnt]=a[i];  
  51.                     else {ok=0;break;}  
  52.                 }  
  53.             }  
  54.             if(ok)printf("Y\n");  
  55.             else printf("J\n");  
  56.          }  
  57.     }  
  58.     return 0;  
  59. }  
posted @ 2018-10-27 16:19  WJEMail  阅读(217)  评论(0编辑  收藏  举报