| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1939 人关注过本帖
标题:四方定理
只看楼主 加入收藏
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 10楼 wmf2014
谬赞了。你我算法的本质区别不在于我使用递归,而是我们遍历的方向不同。你是从小到大,而我是从大到小。观察解的情况我发现它更接近于大端,所以选择这个方向。从小端开始重复计算较多。

如果要遍历所有的解,我也会从小到大计算。因为从小到大的计算范围是1~sqrt(a)/4,而从大到小的计算范围是sqrt(a)~sqrt(a)/4。

最后,认识一下,敝姓杨。姑娘贵姓?

重剑无锋,大巧不工
2015-05-05 00:09
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
回复 11楼 beyondyf
这一会一直在看你的递归函数。
可以肯定,你这不是穷举,而是一种很合理的分解方法,这个方法肯定得不到所有算式(证明四方定理无需穷举所有算式),蓝桥杯四方定理递归用了类似算法。
姓王,希望能得到你的指导。

能编个毛线衣吗?
2015-05-05 00:58
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 12楼 wmf2014
指导不敢当,互相交流吧。

你我对穷举的理解存在差异。举凡搜索我皆视为穷举(或称枚举、遍历)。只不过范围不同而已。比如你虽然是一个数一个数检索,但仍然有一个范围(该数内的最大整数平方根)。

而我的范围要更小一些,比如在前3个数确定的情况下,如果第4个数不是平方数则直接判断其不能构成4方,而不是再一个一个的试。而且我规定了这些平方数的顺序,下一个数必须大于等于前一个数,这样避免了重复的计算。是谓剪枝。

很报歉暂时我没有太多时间解释,有时间咱们可以细细探讨。

送一段可以得到所有解的代码。这两天恐怕没时间来这里玩了,下次再见时如果你还有兴趣的话我们可以好好探讨一下这个问题
程序代码:
#include <stdio.h>
#include <math.h>
int f2(int a, int n)
{
    static int e[5], c;
    int t, i;
    if(n == 4) c = 0;
    t = sqrt(a);
    if(t * t == a)
    {
        printf("%d^2", t);
        for(i = 4; e[i]; printf(" + %d^2", e[i--]));
        puts("");
        return ++c;
    }
    if(n <= 1) return c;
    for(i = t / 4; t >= i; t--)
    {
        e[n] = t;
        f2(a - t * t, n - 1);
        e[n] = 0;
    }
    return c;
}

int main()
{
    int a;
    scanf("%d", &a);
    f2(a, 4);
    return 0;
}


[ 本帖最后由 beyondyf 于 2015-5-5 09:03 编辑 ]

重剑无锋,大巧不工
2015-05-05 09:02
pycansi
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:5
帖 子:418
专家分:1060
注 册:2012-7-26
收藏
得分:0 
问题:

楼主请观察下面两个二进制数
100
1000

提高:

1. 最外层循环欠考虑

2. 采用显式for循环多层嵌套,可扩展性不佳,可以考虑递归形式

......

[ 本帖最后由 pycansi 于 2015-5-5 11:22 编辑 ]


莫问前尘有愧,但求今生无悔
2015-05-05 11:08
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
回复 13楼 beyondyf
得君指点,醍醐灌顶啊!算法学习无止境。
根据提示,修改我的代码如下(即使大数据也瞬间完成,原来的计数法几乎无法完成200000000的所有组合)
程序代码:
#include <stdio.h>
#include <math.h>
void main()
{
    int i,j,k,n,a[4]={0};
    while(1)
    {
        printf("输入验证数(Q/q:退出):");
        if(!scanf("%d",&n))break;
        for(a[0]=(int)sqrt(n);a[0]>0;a[0]--)
        {
            k=a[0]*a[0];
            for(i=1;i<4;i++)
            {
                if(a[i]>a[i-1])break;  //免重复
                a[i]=int(sqrt(n-k));
                k=k+a[i]*a[i];
            }
            if(k==n)
            {
                printf("%d=%d^2",n,a[0]);
                for(i=1;i<4&&a[i];i++)printf("+%d^2",a[i]);
                printf("\n");
            }
        }
    }
}

能编个毛线衣吗?
2015-05-06 09:30
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 15楼 wmf2014
只言片语能让王姑娘觉得有所收获,荣幸之至。不过姑娘的代码还有待商榷之处,如果还有兴趣,可以继续探讨。

题外话,冒昧问下王姑娘从事的是什么职业?

重剑无锋,大巧不工
2015-05-09 01:43
快速回复:四方定理
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028627 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved