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\n");
   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\n",sort[n]-sort[n-1]);
  }
  else
   printf("Impossible\n");
 
 }
 
 return 0;
}

posted @   csgc0131123  阅读(240)  评论(0编辑  收藏  举报
编辑推荐:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
点击右上角即可分享
微信分享提示