151 条题解

  • 1
    @ 2021-03-17 20:15:41
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <deque>
    using namespace std;
    
    namespace dts
    {
        int M;
        
        void main()
        {
            scanf("%d",&M);
            for (int i=1;i<M;i++)
                for (int j=i+1,sum=i;j<M&&sum<M;j++)
                {
                    sum+=j;
                    if (sum==M)
                        printf("%d %d\n",i,j);
                }
        }
    };
    
    int main()
    {
        dts::main();
    }
    
  • 1
    @ 2020-05-22 11:16:48

    一帮只会暴力试的,一点竞赛美学都没。

    首先,这是个数学问题,连续自然数的和为 (首项+末项)* (项数)/2
    所以结果就转换为(begin + end) * (end - begin + 1) / 2 = m
    (begin + end) * (end - begin + 1) = 2 * m = A * B

    将2m进行因数分解
    (begin + end) * (end - begin + 1) = 2 * m = A * B

    begin + end = A
    end - begin + 1 = B

    begin = (A - B + 1) /2
    end = (A + B - 1) /2

  • 0
    @ 2018-07-27 11:48:29

    暴力
    #include<iostream>
    using namespace std;
    int main()
    {
    long long s,k=0;
    double d,S,A,B;
    cin>>s;
    S=s;
    for(int a=2001;a>=2;a--)
    {
    A=a;
    d=S/A;
    if(a%2==1)
    {
    k=d;
    if(d==k&&d>1&&s/a-a/2>0)
    cout<<s/a-a/2<<" "<<s/a+a/2<<endl;

    }

    if(a%2==0)
    {
    k=d*100000;
    if(k%100000==50000&&d>1&&s/a-a/2+1>0)
    cout<<s/a-a/2+1<<" "<<s/a+a/2<<endl;
    }
    }

    }

  • 0
    @ 2017-11-08 16:17:42

    这么水的吗
    像滑动窗口一样的思想

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<bitset>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    template<class T> inline void read(T &_a){
        bool f=0;int _ch=getchar();_a=0;
        while(_ch<'0' || _ch>'9'){if(_ch=='-')f=1;_ch=getchar();}
        while(_ch>='0' && _ch<='9'){_a=(_a<<1)+(_a<<3)+_ch-'0';_ch=getchar();}
        if(f)_a=-_a;
    }
    
    int m,sum=1,l=1,r=1;
    
    int main()
    {
        read(m);
        while(r<m)
        {
            while(sum<m) sum+=++r;
            if(sum==m) printf("%d %d\n",l,r);
            sum-=l++;
        }
        return 0;
    }
    
  • 0
    @ 2017-07-03 12:11:21

    幸好数据小,暴力刷一遍就好了

  • 0
    @ 2016-11-17 19:12:32

    好像没有人用**尺取法**,那就发个题解
    尺取法:像尺蠖蛾一般爬行,不断改变前后区间即可
    2333~
    %下面用**爆枚**与**等差数列**的。
    ```pascal
    program hehe;
    var m,t,i,n:longint;

    begin
    readln(m);

    t:=0;

    for i:=1 to m-1 do
    begin
    if n<=m then n:=n+i;
    while n>m do
    begin
    n:=n-t;
    inc(t);
    end;

    if n=m then writeln(t,' ',i);
    end;
    end.
    ```

  • 0
    @ 2016-10-16 15:40:00

    var i,n,o,min:longint;
    procedure wrt;
    begin
    if n/i-trunc(n/i)=0.5 then _________________;
    else o:=1;
    end;
    procedure wrs;
    begin
    min:=(n div i)-(i div 2);
    end;
    var big:longint;
    begin
    read(n);
    for i:=n div 2 downto 2 do
    begin
    if (n mod i=0) or ((i mod 2=0) and (n mod i<>0)) then begin //判断;
    o:=0;
    if i mod 2=0 then wrt; //偶数
    if i mod 2=1 then wrs; //奇数
    _____________;
    big:=min+i-1;
    write(,' ',);
    writeln;
    end;
    end;
    end.
    //不要依赖,剩下自己想

  • 0
    @ 2016-08-23 22:04:22

    枚举:var
    i,j,m,sum:longint;
    begin
    readln(m);
    for i:=1 to m do
    begin
    sum:=i;
    for j:=i+1 to m do
    begin
    inc(sum,j);
    if sum=m then writeln(i,' ',j);
    if sum>m then break;
    end;
    end;
    end.
    数学:var
    m:longint;
    j,i:int64;
    begin
    readln(m);
    i:=1;
    while i<=m div 2 do
    begin
    j:=1-4*(-i*i+i-2*m);
    if j>=0 then
    begin
    if (((-1+sqrt(j))/2)=trunc((-1+sqrt(j))/2)) and ((-1+sqrt(j))/2>i) then
    writeln(i,' ',trunc((-1+sqrt(j))/2));
    end;
    inc(i);
    end;
    end.
    用数学方法去做数越大这个被开方数就越大 算的比枚举要慢
    在开始时数学方法远快于枚举
    后面枚举快于数学方法
    还有数学方法去做i必须是int64
    i的平方的数据范围和i相同

  • 0
    @ 2016-08-16 19:55:25
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    long long m, ans;
    void init(){
        cin >> m;
    }
    
    long long sol(long long c){
        long long root = (-1 + sqrt(1-4*c))/2;
        if (root*root + root + c == 0) return root;
        else return 0;
    }
    
    int main(){
        //freopen ( "in.txt" , "r" , stdin);
        init();
        
        for (long long i = 1; i <= m/2; i++) {
            if(long long j = sol(i-i*i-2*m)) {
                if(j)
                cout << i << " " << j << "\n";
            }
        }
        return 0;
    }
    
  • 0
    @ 2016-08-14 14:02:37

    AC 150 纪念!
    绝世傻题!!

  • 0
    @ 2016-07-01 22:06:48

    暴力搜索不超时~

    附代码:
    #include <cstdio>
    #include <iostream>

    using namespace std;

    int main(){
    ios::sync_with_stdio(false);
    int m;
    cin >> m;
    for(int i = 1; i < m; i++){
    int sum = 0,begin,end;
    bool isget = false;
    for(int j = i; ; j++){
    if(sum+j == m){ isget = true; begin = i; end = j; break; }
    else if(sum+j > m) break;
    sum += j;
    }
    if(isget) cout << begin << " " << end << endl;
    }

    return 0;
    }

  • 0
    @ 2016-02-18 16:26:08

    刚 绝对不超时
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #include <vector>
    #include <ctime>
    #include <cmath>
    #define N 10000
    using namespace std;

    int n;

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

  • 0
    @ 2015-07-31 18:37:48

    (n+n+x)(x+1)=2M


    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>

    main()
    {
    long m,x;
    scanf("%ld",&m);
    m*=2;
    for (x=floor(sqrt(m));x>=1;x--)
    if ((m%(x+1)==0)&&((m/(x+1)-x)%2==0)) printf("%ld %ld\n",(m/(x+1)-x)/2,(m/(x+1)-x)/2+x);
    }

  • 0
    @ 2015-07-23 14:10:39

    P1302连续自然数和
    Accepted记录信息
    评测状态 Accepted
    题目 P1302 连续自然数和
    递交时间 2015-07-23 14:10:20
    代码语言 C++
    评测机 VijosEx
    消耗时间 30 ms
    消耗内存 276 KiB
    评测时间 2015-07-23 14:10:23

    评测结果
    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 276 KiB, score = 10

    测试数据 #1: Accepted, time = 0 ms, mem = 276 KiB, score = 10

    测试数据 #2: Accepted, time = 15 ms, mem = 272 KiB, score = 10

    测试数据 #3: Accepted, time = 0 ms, mem = 276 KiB, score = 10

    测试数据 #4: Accepted, time = 0 ms, mem = 272 KiB, score = 20

    测试数据 #5: Accepted, time = 15 ms, mem = 276 KiB, score = 20

    测试数据 #6: Accepted, time = 0 ms, mem = 276 KiB, score = 20

    Accepted, time = 30 ms, mem = 276 KiB, score = 100

    代码
    #include <iostream>
    #include <stdio.h>
    #include <math.h>

    using namespace std;

    int i , j;
    int m;
    int k;
    int n;

    int main()
    {
    scanf( "%d" , &m );
    for( k = m ; k >= 1 ; k-- )
    if( 2 * m % ( k + 1 ) == 0 )
    {
    n = ( 2 * m ) / ( k + 1 );
    n -= k;
    n /= 2;
    if( ( 2 * n + k ) * ( k + 1 ) / 2 == m && n >= 0 )
    printf( "%d %d\n" , n , n + k );
    }
    return 0;
    }

  • 0
    @ 2015-06-16 13:40:13

    这道题和CERC2014的一道题很像,不同的是那道题数据很大(n<=10^9,多组数据),我这种做法直接被卡常数卡掉,不过这道题可以过。

    Pascal Code

    var
    n,l,c,d,x,a,b:longint;
    i:longint;
    n2:int64;
    begin
    readln(n);
    n2:=8*n;
    l:=round(sqrt(n2));
    for i:=l downto 1 do
    if (n2 mod i=0)
    then begin
    c:=i;
    d:=n2 div i;
    if odd(c+d) then continue;
    x:=(c+d) div 2;
    if odd(d+1-x) then continue;
    a:=(d+1-x) div 2;
    if odd(x-1) then continue;
    b:=(x-1) div 2;
    if a=b then continue;
    writeln(a,' ',b);
    end;
    end.

  • 0
    @ 2014-11-03 22:58:41

    var
    a1,a2,n,m,i,j,k,s:longint;
    begin
    readln(m);
    k:=trunc(sqrt(2*m));
    for i:=k downto 1 do
    if 2*m mod i=0 then
    begin
    a1:=2*m div i;
    a2:=i;
    if ((a1+a2)mod 2=1)and((a1-a2+1)div 2<>(a1+a2-1)div 2) then
    writeln((a1-a2+1)div 2,' ',(a1+a2-1)div 2);
    end;
    end.

    • @ 2014-11-03 22:59:40

      var
      a1,a2,n,m,i,j,k,s:longint;
      begin
      readln(m);
      k:=trunc(sqrt(2 * m));
      for i:=k downto 1 do
      if 2 * m mod i=0 then
      begin
      a1:=2*m div i;
      a2:=i;
      if ((a1+a2)mod 2=1)and((a1-a2+1)div 2<>(a1+a2-1)div 2) then
      writeln((a1-a2+1)div 2,' ',(a1+a2-1)div 2);
      end;
      end.

  • 0
    @ 2014-10-03 15:13:32

    不需枚举
    program lianxun;
    var m,i:longint;k:int64;
    function solve(a:int64):int64;
    var delta:int64;s:real;
    begin
    delta:=1-4*(a-sqr(a)-2*m);
    if delta<0 then exit(0);
    s:=sqrt(delta);
    if trunc(s)-s<>0 then exit(0);
    if trunc(s) mod 2=0 then exit(0);
    exit((trunc(s)-1)div 2);
    end;

    begin
    readln(m);
    for i:=1 to m div 2 do
    begin
    k:=solve(i);
    if k=0 then continue
    else writeln(i,' ',k);
    end;
    end.

  • 0
    @ 2014-08-19 21:42:13

    测试数据 #0: Accepted, time = 0 ms, mem = 608 KiB, score = 10

    测试数据 #1: Accepted, time = 0 ms, mem = 612 KiB, score = 10

    测试数据 #2: Accepted, time = 0 ms, mem = 612 KiB, score = 10

    测试数据 #3: Accepted, time = 0 ms, mem = 612 KiB, score = 10

    测试数据 #4: Accepted, time = 0 ms, mem = 612 KiB, score = 20

    测试数据 #5: Accepted, time = 0 ms, mem = 612 KiB, score = 20

    测试数据 #6: Accepted, time = 15 ms, mem = 612 KiB, score = 20

    Accepted, time = 15 ms, mem = 612 KiB, score = 100

    今日开始刷Vj的留念!!感觉Pascal代码一长就各种恶心= =所以风格要非主流
    设n=i*m,把i从2到n-1循环
    如果n MOD i=0,
    若i此时为奇数 说明有i个连续的整数加起来为n,就且中位数为m(要加个判断看是不是都是自然数)
    若此时i为偶数且m为整数,不可能(因为偶数个连续整数中位数一定是1/2整数倍)
    若此时i为偶数且m为 什么什么点5(XX.5,就是1/2整数倍),则有i个连续整数何为n,m为中位数

    = =貌似有点绕,其实我自己也有点棘手,F7了半天……
    那就上代码

    code(pascal):

    var
    n,i,m,r:longint;
    f:boolean;
    begin
    readln(n);
    for i:=trunc(n*2/3) downto 2 do
    begin
    if i mod 2=1then begin
    m:=n div i;
    if(n mod i=0)and(m-i div 2>=0)and(m+i div 2<=n)then
    writeln(m-i div 2,' ',m+i div 2);
    end
    else begin
    r:=n div i;
    if((2*n)mod i=0)and(n mod i<>0)and(r-i div 2-1>=0)and(r+i div 2+1<=n)then
    writeln(r-i div 2+1,' ',r+i div 2);
    end;
    end;
    end.

  • 0
    @ 2014-08-06 11:46:48

    超短代码

    #include <stdio.h>
    int main(){
    int i,k,m,sum;
    scanf("%d",&m);
    for(i=0;i<m;i++){
    sum=0;
    for(k=i;sum<m;k++) sum+=k;
    if(sum==m) printf("%d %d\n",i,k-1);
    }
    return 0;
    }

  • 0
    @ 2014-01-26 14:12:58

    枚举即可

    一开始走的弯路我就不展示了
    设b=a+k
    所以

    (2a+k)(k+1)=2m
    m-k(k+1)/2=a(k+1)>0
    所以
    k<sqrt(2m)<2^16<40000
    然后枚举k即可求a=(m-k(k+1)/2)/(k+1) (当然a得是整数吧,a要大于0吧)
    注释掉的是一开始走弯路的.设的是a,b枚举的是b,b的范围比较大,肯定超时,而且每枚举一次还要开方.

    #include<stdio.h>
    #include<math.h>
    int main()
    {
    unsigned long long m;
    int a,b,x,k;
    double xx;
    scanf("%lld",&m);
    xx=sqrt(m<<1); k=(int)floor(xx);
    if (!(fabs(xx-k) < 1e-6)) k++;
    while (k) {
    if (k&1) x=((k+1)>>1)*k; else x=(k>>1)*(k+1);
    x=m-x;
    if (x%(k+1) == 0) {
    a=x/(k+1);
    b=a+k;
    if (a>0)
    printf("%d %d\n",a,b);
    }
    k--;
    }
    return 0;
    }

信息

ID
1302
难度
3
分类
数论 | 数位统计 点击显示
标签
(无)
递交数
2421
已通过
1275
通过率
53%
被复制
2
上传者