lsmCC 发表于 2023-11-24 21:36:14

又是双指针问题

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m;
int main()
{
    cin>>m;
    int i=1,j=1,sum=1;
    while(i<=m/2)
    {
      j++;
      sum+=j;
   
    if(sum>=m)
    {
      if(sum==m)cout<<i<<j<<endl;
      sum-=i;
      i++;
    }
    }

}
为什么会没有输出呢
题目链接:https://www.luogu.com.cn/problem/P1147

FishC_GPT 发表于 2023-11-24 21:36:46

在你的代码中,你将`=`号误写成了`==`号,在`while`循环的条件判断中应该改为`while(i == m)`。另外,你没有对`sum`进行更新操作,所以无法退出循环。在每次循环结束后,你需要更新`sum`的值。以下是修正后的代码:

#include <iostream>
using namespace std;
typedef long long ll;
ll m;

int main()
{
    cin >> m;

    int i = 1, j = 1, sum = 1;
    while (i <= m)
    {
      if (sum == m)
            cout << i << " " << j << endl;
      
      if (sum <= m)
      {
            j++;
            sum += j;
      }
      else
      {
            sum -= i;
            i++;
      }
    }

    return 0;
}

这段代码使用了双指针的思想来解决问题。其中,变量`i`代表当前的起始位置,变量`j`代表当前的结束位置,变量`sum`代表从`i`到`j`的连续整数的和。如果`sum`等于目标值`m`,则输出`i`和`j`。然后,根据`sum`与`m`的关系来移动`i`和`j`的位置,使得`sum`接近`m`。

希望能帮到你!
以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

tommyyu 发表于 2023-11-24 21:56:10

本帖最后由 tommyyu 于 2023-11-24 21:59 编辑

你这种做法不一定能找到答案,可以用二元二次方程。
由题意得,x + (x+1) +... +y = m
而 x + (x+1) + ... + y = (1 + ... + y) - (1 + ... + (x-1))
                                 = (y+1)*y/2 - (x-1)*x/2
此时枚举 x 的值,有
(y+1)*y/2 - (x-1)*x/2 = m
(y+1)*y - (x-1)*x = 2*m
(y+1)*y = 2*m+(x-1)*x
此时就有一种快速计算y的方法,先算出右边的值,再直接开根号得到一个小数,此时将这个小数变为整数,即有可能是 y 的值,之后计算验证即可。#include <iostream>
#include <cmath>
using namespace std;
int main()
{
        long long m, x, y; cin >> m;
        for(x=0; x<m; ++x) {
                y = (long long)sqrt(2*m+(x-1)*x);
                if(y*(y+1) - x*(x-1) == 2*m && x < y) cout << x << " " << y << endl;
        }
        return 0;
}
ps: 我第一次试的时候没开 long long 就爆了{:10_266:}
页: [1]
查看完整版本: 又是双指针问题