• 山东大学考研机试题——整数序列


    题目描述

    传送门——AcWing 3717. 整数序列 - AcWing

    很多整数可以由一段连续的正整数序列(至少两个数)相加而成,比如 25=3+4+5+6+7=12+1325=3+4+5+6+7=12+13。

    输入一个整数 N,输出 N 的全部正整数序列,如果没有则输出 NONE

    输入格式

    一个整数 N。

    输出格式

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

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

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

    数据范围

    2 ≤ N ≤ 107

    输入样例:

    25

    输出样例:

    3 4 5 6 7
    12 13

    思路及代码

    二分查找

    从 1 ~ n / 2 遍历 i,通过二分查找以 i 开头时的答案。

    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. const int N = 1e7+7;
    5. int n;
    6. int main(){
    7. std::ios::sync_with_stdio(false);
    8. std::cin.tie(0);
    9. std::cout.tie(0);
    10. cin>>n;
    11. LL k = n / 2;
    12. bool tag = false;
    13. for(LL i=1;i<=k;i++){
    14. // high = k + 1作为最大值是因为当最大值大于 n/2时,由于要求是一组连续的数,所以此时的序列至多有2个数
    15. LL low = i, high = k + 1;
    16. while(low < high){
    17. LL mid = low + high + 1 >> 1;
    18. if((mid - i + 1)*(i + mid) <= 2*n){
    19. low = mid;
    20. }else{
    21. high = mid -1;
    22. }
    23. }
    24. if((low - i + 1)*(i + low) == 2*n){
    25. tag = true;
    26. for(int j=i;j<=low;j++){
    27. cout<" ";
    28. }
    29. cout<<"\n";
    30. }
    31. }
    32. if(tag == false){
    33. cout<<"NONE";
    34. }
    35. return 0;
    36. }

    数学公式

    该题本质考察的是一组连续数的和,则令这组连续数的开头是a,共k个数,那么这组数的和通过求和公式可得为 (a + a + k - 1) * k / 2。而我们需要求得是 a 和 k,当这两个未知数确定后,一组数便确定了。

    因此考虑, (a + a + k - 1) * k / 2 = n,即 (2a + k - 1) * k = 2n,可知,由 a 和 k 组成的 y = (2a + k - 1) 和 x = k 两个公式是 2n 的因子。既然如此,我们可以去求 2n 的因子,考察满足条件的两个因子 x和y,由 x和y 可得到 a 和 k。

    1. #include
    2. using namespace std;
    3. int main() {
    4. std::ios::sync_with_stdio(false);
    5. std::cin.tie(0);
    6. std::cout.tie(0);
    7. int n;
    8. cin >> n;
    9. n *= 2;
    10. int cnt = 0;
    11. // 题目要求优先输出首项更小的序列,即 (2a + k - 1) * k 中的 a 更小。由 (2a + k - 1) * k = 2n 可知 k 越大 a越小,即因子 x 越大,a越小,所以这里 x 从大到小遍历
    12. for (int x = sqrt(n); x > 1; x--) {
    13. if (n % x == 0) {
    14. int y = n / x;
    15. int t = y - (x - 1);
    16. // t = 2a,因此 t 必须是偶数
    17. if (t % 2 == 0) {
    18. cnt++;
    19. int a = t / 2;
    20. for (int i = a; i < a + x; i++) {
    21. cout << i << " ";
    22. }
    23. cout << "\n";
    24. }
    25. }
    26. }
    27. if (cnt == 0) {
    28. cout << "NONE";
    29. }
    30. return 0;
    31. }

  • 相关阅读:
    《lwip学习10》-- TCP协议
    LeetCode 78 Java 实现
    RocketMQ源码阅读(九)DefaultMQProducer消息发送
    软件测试需要学习什么?好学吗?需要学多久?到底是报班好还是自学好?
    图解LeetCode——面试题 01.08. 零矩阵(难度:中等)
    Linux环境下离线安装jdk1.8(内置最新的jdk安装包x64)
    13 mysql date/time/datetime/year 的数据存储
    七、Docker网络模式详解
    修剪二叉搜索树likou669
    Web爬虫--fofa-资产信息搜集
  • 原文地址:https://blog.csdn.net/qq_64431512/article/details/140908438