山东大学考研机试--AcWing 3717. 整数序列

题目描述

很多整数可以由一连串的整数序列(至少两个数)相加而成,比如 25=3+4+5+6+7=12+13。输入一个整数 N,输出 N
的全部整数序列,如果没有则输出 NONE。

输入格式

一个整数 N。

输出格式

每行输出一个满足条件的整数序列。

序列内部元素从小到大排序。

优先输出首项更小的序列。

数据范围

2⩽N⩽1e7

输入样例

25

输出样例

3 4 5 6 7
12 13

题意分析

首先看到是将一个数拆为连续的一段序列,实际上就是求在整数的序列中求是否有一段的连续的和,此时我们就应该警觉,因为其包含使用二分法的两个关键要素:

  • 一段有序的序列(整数序列)
  • 一个查找条件(序列内各数的和为n)
    因此我们就要考虑使用二分法
    y总的二分法模板
bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid; // check()判断mid是否满足性质
else l = mid + 1;
}
return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}

所以对于这道题只需要根据从a到b的连续的大小为(a+b)/2*(b-a+1)

CODE

#include<iostream>
using namespace std;
#define int long long
const int N=1e7+10;
int n;
bool st;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n/2;i++)
{
int l=i+1,r=n/2+1;
while(l<r)
{
int mid=l+r>>1;
int x=(i+mid)*(mid-i+1)/2;//二分的条件 标准的二分模板
if(x>=n)r=mid;
else l=mid+1;
}
if((i+r)*(r-i+1)/2==n)
{
for(int j=i;j<=r;j++)cout<<j<<' ';
cout<<endl;
st=1;
}
}
if(!st)puts("NONE");
return 0;
}
posted @   liuwansi  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示