• 74.Interesting Sequence(有趣的数列)(拓扑排序)


    Interesting Sequence(有趣的数列)[Special judge]

    题目概述:是否存在一个长度为n的整数数列,其任意连续p项之和为正数而任意连续q项之和为负数?

     

    方法:连续项a[i],a[i+1]...a[j]和的性质容易联想到以前n项和的方式表达,即s[j]-s[i],简洁明了。

    由此发现只需求一个满足要求的s[0]~s[n]。

    其中s[i+p]-s[i]>0,s[i]-s[i-q]<0。即s[i]

    同理有s[i]>s[i-p],s[i+q]。

     

    这是拓扑排序的雏形。

     

    更幸运的是,由于需要存在初始s[i]最大(拓扑排序起点),即要求存在i,使得s[i+p],s[i-q]不存在,故i+p>n,i-q<0,=>p+q>=n+2。

    这表明s[i+p],s[i-q]最多只有一个存在(每个节点最多只有一个入度)。

    s[i-p],s[i+q]也最多只有一个存在(每个节点最多只有一个出度)。

    因此拓扑排序时只要删除一个入度就能进队列,无需额外记录节点入度。

    代码:

    #include
    #include
    using namespace std;
     
    //sort记录s[i]的大小,
    //sort[i]>sort[j]=>s[i]>s[j],
    //sort[i]-sort[0]=s[i]-s[0]=s[i],
    //a[i]=sort[i]-sort[i-1]。
    int sort[1000001];
     
    int main(){

     int t,n,p,q,m,i,j;
     queue mq;
     scanf("%d",&t);

     while(t--){
      scanf("%d %d %d",&n,&p,&q);
     
      if(p+q
       printf("Impossible ");
       continue;
      }
     
      m=n;
      for(i=n-p+1;i<=q-1;i++)
       mq.push(i);
     
      while(!mq.empty()){ //拓扑排序
       i=mq.front();
       mq.pop();
       sort[i]=m--;
       if(i-p>=0)
        mq.push(i-p);
      
       else if(i+q<=n)
        mq.push(i+q);
      
      }
     
      if(m==-1){
       for(i=1;i<=n-1;i++)
       printf("%d ",sort[i]-sort[i-1]);
       printf("%d ",sort[n]-sort[n-1]);
      }
      else
       printf("Impossible ");
     
     }
     
     return 0;
    }

  • 相关阅读:
    .net中使用事务 dodo
    dnn中NULL值的处理 dodo
    通过sql server的作业调度+存储过程来实现系统定时任务的方法 dodo
    使用With...End With dodo
    ASP.NET页面中使用SolpartMenu控件 dodo
    浅解web打印 dodo
    WEB打印大全(转) dodo
    AjaxMethod未定义原因 dodo
    CommandEventArgs.CommandArgument 属性 dodo
    在用VS.NET2003 新建项目时系统提示 autometion服务器无法创建对象 这是什么问题? dodo
  • 原文地址:https://www.cnblogs.com/csgc0131123/p/5290316.html
Copyright © 2020-2023  润新知