美文网首页编程练习-解题报告
#hihocoder1372# 平方求和

#hihocoder1372# 平方求和

作者: diskang | 来源:发表于2016-10-07 01:43 被阅读99次

题目1372:

平方求和

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

对于一个非负整数n,最少需要几个完全平方数,使其和为n?

输入

输入包含多组数据。对于每组数据:
第一行是n;如果n为-1,表示输入结束。(0 <= n <= 1000000001)

输出

针对每组数据,输出最少需要的完全平方数。

样例输入

3
4
5
-1

样例输出

3
1
2


解题:

一开始的思路:动态规划

结果:超空间

动态规划是很自然的想法,每个N都可能是一个平方a 和其它平方s的和组成,通过控制平方数a的大小,并利用之前已经得到的答案,选择其中的最小值作为N的答案。
但是很显然,1000000002*sizeof(short)远远超出了空间限制。
不过开始在没有别的好办法的情况下,我还是写了,至少得点基础分吧。

short *table = new short [max_n+1];
table[0]=0;
table[1]=1;
for(int i=2;i<=max_n;i++){
    short min_count=table[i-1]+1;
    for(int j=1;j*j<=i;j++){
        int new_count = table[i-j*j]+1;
        if(new_count<min_count)min_count = new_count;
    }
    table[i]=min_count;
}

苦思冥想后的意外收获:四方定理

一时间没想到好办法,用第一种方法打印了前1000个数的解。如图

220216164030306082.jpg

非常有规律啊,我不禁猜测可能最大的答案就是4。
然后按图索骥,我找到了

四方定理:
所有自然数至多只要用四个数的平方和就可以表示。

顺便贴一个证明:

http://planetmath.org/proofoflagrangesfoursquaretheorem

改进的思路:位运算

结果:超时间

有了四方定理,可以简化问题,只要不属于1、2、3,答案必定是4无疑。
然后考虑到空间不足。设计了新方案:
使用位运算,数字i能否被分解就由第i位来标记,1个、2个、3个平方和就需要三个变量,分别是once,twice,third

const int MAX_N = 1000000002;
class SpaceArray {
    public:
        bitset<MAX_N> once;//only for  query
        bitset<MAX_N> twice;
        bitset<MAX_N> third;
};

once时间复杂度: O(根号N)
twice需要once中标记为平方的位数,嵌套两次相加而得,时间复杂度为O(N)
third同理,需要once和twice里位数的和, O(N^(3/2))

注:把3个变量once、twice、third封装到class里,是为了 new 这个class,这种调用方式是在堆中分配内存,可以很大;相反,直接使用是在栈中调用,会报错-栈空间不够。
顺便复习了一下堆栈的知识,可怜我半吊子的C++水平。

最终的解决

放弃把表里每个值都求出来的思路了,现在只考虑输入的这个N;
采用方法:求根后取整再平方和原值比较。

bool check1(int number) {//是否一个平方组成
    int a = int(sqrt(number));
    return a*a == number;
}
bool check2(int number) {//是否两个平方和组成
    for (int i = 1, i2 = i*i; i2<number; i2+=(2*i+1), i++) {
        if (check1(number - i2))return true;
    }
    return false;
}
bool check3(int number) {//是否三个平方和组成
    for (int i = 1, i2 = i*i; i2<number; i2 += (2 * i + 1), i++) {
        if (check2(number - i2))return true;
    }
    return false;
}

根据四方定理,不是以上三者的都属于4个平方和可以组成的。
3个函数求值的时间复杂度如下
O(1)
O(N^1/2)
O(N)

一直WA的原因:0

开始一直以为输入0,输出也应该是0(0个完全平方的和是0)
走投无路,开始想各种可能性。结果这道题把0本身也看成是完全平方,无语。即 0 = 0 * 0,所以答案是1。

相关文章

  • #hihocoder1372# 平方求和

    题目1372: 平方求和 时间限制:1000ms单点时限:1000ms内存限制:256MB 描述 对于一个非负整数...

  • 202. Happy Number - swift

    给定一个整数n,计算n每位上数的平方,然后求和(后面简称这个过程为:平方求和)。平方求和的结果继续平方求和,直到平...

  • 平方和求和

    问题 求 1^2 + 2^2 + 3^2 + 4^2 + ... + n^2 = ? 解决思路 去掉之前乱七八糟的...

  • 奥数 | 玩转小奥数

    一、整数裂项 二、平方求和与立方求和 三、周期性工程问题 四、列方程解应用题

  • 2018-01-22 学习

    //一个数平方之后,逆序与原来相等 #include int reverse(int x){//倒序求和 int...

  • ARTS第五周

    Algorithm leetCode 202 Happy Number将数字的每一个数字平方求和,如果等于1就是h...

  • Excel(二)

    平方根函数SQRT 求和函数SUM 求平均值函数AVERAGE COUNT函数 COUNTA函数 条件计数函数CO...

  • 工作小技巧

    Excel 数据求和 alt+= 美化表格 Ctrl+L 生成图表 alt+F1 平方 alt+178 立方 al...

  • 什么是L1 范数

    给定向量x=(x1,x2,...xn)L1范数:向量各个元素绝对值之和L2范数:向量各个元素的平方求和然后求平方根...

  • HDU-4027-Can you answer these qu

    思路:题目中的每次改值都是变成原来的平方根,然而平方根好像没有求和公式啥的,,找不出来。而且发现很大的数经过几次操...

网友评论

    本文标题:#hihocoder1372# 平方求和

    本文链接:https://www.haomeiwen.com/subject/krhyyttx.html