• HDU 2058 The sum problem (数学+暴力)


    题意:给定一个N和M,N表示从1到N的连续序列,让你求在1到N这个序列中连续子序列的和为M的子序列区间。

    析:很明显最直接的方法就是暴力,可是不幸的是,由于N,M太大了,肯定会TLE的。所以我们就想能不能优化一下,找一个范围。想到这是一个连续的序列而且是从1开始的,这不就是一个等差数列么,公差是1罢了。由求和公式得Sn = (a1+an) * n / 2;所以说n最大就是sqrt(M*2)(想一想为什么),因为a1+an 一定是大于n的。如果我们取区间的和,那么Sn = (ai+aj) * (j-i+1)/2;以上我们可得到一个方程,i+j = M/n(当然n|M),j-i+1 = n;所以我们可以解出i和j,其他的就简单了从n到1暴一遍就OK。

    当我做完后我又看了网上的题解,我个去,写的比我简单多了。。。

    他们是这么说的,等差数列的运用。Sn = (a1+an) * n / 2 = (a1 + a1 + (n - 1) * d)*n/2。

    解题公式变形:(a+a+len)*(len+1)/2 = m => a = m/(len+1)-len/2 (m是已知条件,len的最大值为sqrt(2*m))。

    代码如下:

    这是我写的代码:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    
    using namespace std;
    
    int main(){
        int n, m;
        while(scanf("%d %d", &n, &m)){
            if(!n && !m)  break;
            m <<= 1;
            int len = (int)sqrt(m) + 1;
    
            while(--len){
                if(n > len && m % len == 0){
                    if((len + m / len - 1) % 2)  continue;
                    int j = (len + m / len - 1) / 2;
                    if(j > n || j < 0)  continue;
                    int i = m / len - j;
                    if(i > n || i < 0)  continue;
                    if(i > j)  swap(i, j);
                    printf("[%d,%d]
    ", i, j);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    

    下面是题解的代码:

    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    int main()
    {
        int n, m, a, len;
        while (scanf("%d%d", &n, &m) && (n || m))
        {
            len = (int)sqrt(2*m);
            while (len--)
            {
                a = m / (len + 1) - len / 2;
                if ((2*a+len) * (len+1) / 2 == m)
                    printf("[%d,%d]
    ", a, a+len);
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Spring 事务XML配置
    启用事务注解
    ebay 店铺状态
    lambda Map Reduce
    sublime3注册码
    使用多线程
    Spring AOP学习(六)
    添加依赖库
    CodeForces 867B Save the problem
    POJ 3264 Balanced Lineup (线段树查找最大最小值)
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5526275.html
Copyright © 2020-2023  润新知