ds解题报告

来源:互联网 发布:文泰刻绘2002解密软件 编辑:程序博客网 时间:2024/06/07 04:57

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4.2

题意:三种操作:

IN x:x进队

OUT:出队

QUERY:查询队伍中最大值

题解:x进队时,如果队伍前面的数y比他小,那么对于某次包含x的查询,y肯定没有贡献。所以维护一个单调递减的栈,保存每个数进队时间。具体操作看代码。

#include<cstdio>  #include<string>  #include<iostream>  using namespace std;  const int N=100020;  int a[N],t[N];  int main() {      string s;      int ti=0,to=0,p=0,q=0;      while(cin>>s) {          if(s=="END") break;          else if(s=="IN") {              int x;scanf("%d",&x);              while(p<q&&a[q]<x) --q;              a[++q]=x;t[q]=++ti;          }else if(s=="OUT") {              if(t[p+1]<=++to) ++p;          }else if(s=="QUERY") {              printf("%d\n",p<q?a[p+1]:-1);          }      }      return 0;  }  

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4.4

题意:在数组a[1~n]中寻找最长的连续子序列,使他们的最大最小值之差在[m,k]之间

题解:滑窗法,对于l和r,维护他们的最大最小值(很明显,维护的方法和上面的一样)。

#include<cstdio>  #define max(a,b) (a>b)?(a):(b)  const int N=10005;  int a[N];  struct Node {      int val,i;  }Max[N],Min[N];   int main() {      int n,m,k,i,ans,l,r,p1,q1,p2,q2,tmp;      while(~scanf("%d%d%d",&n,&m,&k)) {          for(i=1;i<=n;++i) scanf("%d",&a[i]);          ans=0;p1=q1=p2=q2=0;          //划窗          //需要维护l~r的最小值和最大值           for(l=r=1;r<=n;++r) {              //维护一个单调递减的栈              while(p1<q1&&Max[q1].val<a[r]) --q1;              Max[++q1].val=a[r];              Max[q1].i=r;              //维护一个单调递增的栈              while(p2<q2&&Min[q2].val>a[r]) --q2;              Min[++q2].val=a[r];              Min[q2].i=r;                            while(l<r) {                  while(Max[p1+1].i<l) ++p1;                  while(Min[p2+1].i<l) ++p2;                  tmp=Max[p1+1].val-Min[p2+1].val;                  if(tmp<=k) break;//m<=tmp&&                  else ++l;              }              if(m<=tmp) ans=max(ans,r-l+1);          }           printf("%d\n",ans);      }       return 0;  }   /* 5 0 0 1 1 1 1 1  6 0 3 3 1 2 3 4 5  6 0 2  3 1 2 3 4 5 */   

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5.1

题意:求给定序列中,连续子序列和的绝对值的最小值。

题解:见代码。

#include<cstdio>#include<cstring>#include<algorithm>#define min(a,b) (a<b)?(a):(b)using namespace std;typedef __int64 ll;const int N=100005;ll a[N];int main() {    int n,i;    ll x,ans;    while(~scanf("%d",&n)) {         for(i=1;i<=n;++i) {            scanf("%I64d",&x);            a[i]=a[i-1]+x;         }         sort(a+1,a+1+n);         ans=abs(a[1]);         for(i=2;i<=n;++i) {            ans=min(ans,a[i]-a[i-1]);            ans=min(ans,abs(a[i]));         }         printf("%I64d\n",ans);    }    return 0;}




0 0
原创粉丝点击