micolar 发表于 2019-8-16 22:25:32

连续自然数和(用了俺三分之一的鱼币。)

这是我学校上的一道编程题

下面是我的代码
#include<stdio.h>
#include<math.h>
void createRealDivisors(int n){
    int nRoot= (int)sqrt(2*n),a,i,count = -1;
    for( i = 2; i <= nRoot;i++){
      if(!(2*n%i)){
            printOutcome(i,2*n/i);
            a[++count] = i;
      }
    }
    if (!(2*n - a * a))
      count--;
    for(i = count;i >= 0;i--)
      printOutcome(2*n / a,a);
}

void printOutcome(int a,int b){

    if(a%2 ^ b%2 && a+1-b >= 0){
      int left = (a+1-b) / 2;
      int right = left + b - 1;
      printf("%d %d\n",left,right);
    }
}


int main(){
    int n;
    scanf("%d",&n);
    createRealDivisors(n);
    return 0;
}


我是用等差算出中差 再用个数算出第一项和最后一项
以为对了 但是提交上去还是错了

错了就改 关键是学校网不给看错在哪俺很难受

我陷入我的思维很难找到我错的地方
大佬们,求助啊

zykt 发表于 2019-8-16 22:25:33

#include<bits/stdc++.h>
using namespace std;
int m;
int main(){
    cin>>m;
    for(int k1=sqrt(2*m);k1>1;k1--)//枚举k1(注意是k1>1而不是k1>=1)
      if(2*m%k1==0 && (k1+2*m/k1)%2){//如果K2是整数而且与K1一奇一偶
            int k2=2*m/k1;
                cout<<(k2-k1+1)/2<<" "<<(k1+k2-1)/2<<endl;//输出答案
      }
    return 0;
}

ba21 发表于 2019-8-16 23:11:42

换个方法实现试试,比如暴力法。可能它不赞同你的方法。。

迷雾少年 发表于 2019-8-16 23:32:25

本帖最后由 迷雾少年 于 2019-8-16 23:38 编辑

思路:滑动窗口
#include <iostream>
#include <vector>
#include <cctype>
/*使用迭代器将输入的数字翻倍输出*/
using namespace std;
int main(int argc, char const* argv[])
{
        int lf = 0, rg = 1,sum=lf+rg;
        int M = 10000;//2+3+4
        while (lf<rg && lf<=1000000000)
        {
                if (sum < M) {
                        rg++;
                        sum += rg;
                }
                else if(sum == M)
                {
                        cout << "lf:" << lf << " " << "rg:" << rg << endl;
                        sum -= lf;
                        lf++;
                }
                else
                {
                        sum -= rg;
                        rg--;
                       
                       
                        sum -= lf;
                        lf++;
                       
                }
        }

       
        return 0;
}


输入输出

lf:18 rg:142
lf:297 rg:328
lf:388 rg:412
lf:1998 rg:2002
请按任意键继续. . .

micolar 发表于 2019-8-16 23:36:11

ba21 发表于 2019-8-16 23:11
换个方法实现试试,比如暴力法。可能它不赞同你的方法。。

n的值为1000000000
亲,暴力是会掉头发的
我有在网上找个暴力的跟我程序的答案对比下 我所输的n对应的值都一样
我思路是对的
我想要知道我程序错在哪
是遗漏了什么值 还是逻辑上的错误 还是定义内存太大溢出
如果了解编译机制就好多了

迷雾少年 发表于 2019-8-16 23:41:23

ba21 发表于 2019-8-16 23:11
换个方法实现试试,比如暴力法。可能它不赞同你的方法。。

看到这个M的级数暴力(O^2)就不可能了

micolar 发表于 2019-8-16 23:47:39

迷雾少年 发表于 2019-8-16 23:41
看到这个M的级数暴力(O^2)就不可能了

我们学校c超过一秒就不行了
单循环也不行的

俺不是要解决这道题才发这道贴的。。。
不过谢谢你们

zykt 发表于 2019-8-18 10:18:09

这个方法行

zykt 发表于 2019-8-18 10:19:32

或者这个
#include<cstdio>

int m;

int main()
{
    scanf("%d",&m);
    int sum=3;
    for(int i=1,j=2;i<=m/2;)
    {
      if(sum==m)
      {
            printf("%d %d\n",i,j);
            sum-=i;
            i++;
      }
      else if(sum<m)
      {
            j++;
            sum+=j;
      }
      else
      {
            sum-=i;
            i++;
      }
    }
    return 0;
}

micolar 发表于 2019-8-18 13:44:05

zykt 发表于 2019-8-18 10:17
#include
using namespace std;
int m;


看了你的程序我知道错哪了


假如m 是 10

结果你输出1 4
我是 0 4
       1 4
题目说是说自然数

而且因为每一项都是大于1 的递增序列 所以项数不可能超过m的一半

#include<stdio.h>
#include<math.h>
void createRealDivisors(int n) {
        int nRoot= (int)sqrt(2*n),i;
        for( i = nRoot; i >= 2; i--)
                if(!(2*n%i))   //求因子
                        printOutcome(2*n/i,i); //判断,输出
}
void printOutcome(int a,int b) {
        if(a%2 ^ b%2 && a+1-b > 0) { //判断奇偶我用了异或,
                int left = (a+1-b) / 2;//中差除以2,距离除以2 ,我把它们先加起来在除以二避免类型转换
                int right = left + b - 1;
                printf("%d %d\n",left,right);
        }
}


int main() {
        int n;
        scanf("%d",&n);
        createRealDivisors(n);
        return 0;
}
刚刚拿你的程序先过
然后我改了我的也过了

谢了{:5_109:}
页: [1]
查看完整版本: 连续自然数和(用了俺三分之一的鱼币。)