一个关于从1到100的加法算法

Dearsoul 2006-09-01 04:40:12
从1到100,100个数字相加,和为100的算法,可以1位,2位,3位等,不限位数相加,数字不能重复,可以有多少种算法,并把代码贴出;
可以这样:
1 + 99;
2 + 98;
也可以这样:
1 + 2 + 97;
更可以这样:
1 + 2 + 3 + 5 + 7 + 82;

...全文
2326 55 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
pig4210 2006-09-07
  • 打赏
  • 举报
回复
.586
.model flat,stdcall
option casemap:none

include windows.inc

include user32.inc
include kernel32.inc
include shell32.inc
include masm32.inc

includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib masm32.lib

include C:\masm32\macros\MACROS.ASM

.data
fmt_num db "%d",0
fmt_my db "%d+%d+%d+%d+%d+%d+%d+%d+%d+%d+%d+%d+%d",10,0
szDestClass db 'Notepad',0
fmt_result db '计算结果:共计:%d 计算耗时:%d ms',0

.data?
hInstance dd ?
tmpstr db 128 dup (?)



.code

;结果输出
_SendtoNotepad proc _lpsz
local @hWinNotepad

invoke FindWindow,addr szDestClass,NULL
.if eax
mov ecx,eax
invoke ChildWindowFromPoint,ecx,20,20
.endif
.if eax
mov @hWinNotepad,eax
mov esi,_lpsz
@@:
lodsb
or al,al
jz @F
movzx eax,al
invoke PostMessage,@hWinNotepad,WM_CHAR,eax,1
jmp @B
@@:
.endif
ret

_SendtoNotepad endp





;eax=0 now为0

;my(num[1]...num[13],j)
;{
; num[j+1]=num[j]-num[j-1];
; num[j]=num[j-1];
; for(1)
; {num[j]++;
; num[j+1]--;
; for(i=j;i<13;++i)
; { my (num[1],num[2],..num[13],i);}
; if(num[j+1]<num[j])
; {break;}
; cout++;
; }
;}
;my(1,99,0,0,0,0,0,2);
_cout proc @n,@n2,@n3,@n4,@n5,@n6,@n7,@n8,@n9,@n10,@n11,@n12,@n13,@i

mov ecx,@i
mov eax,@n[ecx]
mov edx,@n[ecx-4]
sub eax,edx

@@: inc edx
dec eax
.if eax <= edx
xor eax,eax
ret
.endif
mov @n[ecx+4],eax
mov @n[ecx],edx
inc edi
;如果需要结果输出的话,下面一段可用,但时间上很慢好像。
; push eax
; pushad
; invoke wsprintf,addr tmpstr,addr fmt_my,@n,@n2,@n3,@n4,@n5,@n6,@n7,@n8,@n9,@n10,@n11,@n12,@n13
; invoke _SendtoNotepad,addr tmpstr
; popad
; pop eax

.if ecx < 2ch
add ecx,4
invoke _cout,@n,@n2,@n3,@n4,@n5,@n6,@n7,@n8,@n9,@n10,@n11,@n12,@n13,ecx
.endif
mov ecx,@i
mov edx,@n[ecx]
mov eax,@n[ecx+4]
jmp @B

_cout endp


_main proc

LOCAL @num1
LOCAL @num2

pushad

invoke GetTickCount
mov ebx,eax ;用ebx做时钟计数

xor edi,edi ;用edi做计数器

push 1
pop @num1
push 99
pop @num2

.while @num1 < 50
invoke _cout,@num1,@num2,0,0,0,0,0,0,0,0,0,0,0,4
inc edi
inc @num1
dec @num2
.endw

invoke GetTickCount
sub eax,ebx

invoke wsprintf,addr tmpstr,addr fmt_result,edi,eax
invoke MessageBox,NULL,addr tmpstr,NULL,MB_OK

popad
ret

_main endp


start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke _main
invoke ExitProcess,NULL
end start
jailu 2006-09-05
  • 打赏
  • 举报
回复
随手用C#写了一下实现代码,部分结果如下:
...
1+2+3+4+5+6+7+8+9+10+14+15+16
1+2+3+4+5+6+7+8+9+11+12+13+19
1+2+3+4+5+6+7+8+9+11+12+14+18
1+2+3+4+5+6+7+8+9+11+12+15+17
1+2+3+4+5+6+7+8+9+11+13+14+17
1+2+3+4+5+6+7+8+9+11+13+15+16
1+2+3+4+5+6+7+8+9+12+13+14+16
1+2+3+4+5+6+7+8+10+11+12+13+18
1+2+3+4+5+6+7+8+10+11+12+14+17
1+2+3+4+5+6+7+8+10+11+12+15+16
1+2+3+4+5+6+7+8+10+11+13+14+16
1+2+3+4+5+6+7+8+10+12+13+14+15
1+2+3+4+5+6+7+9+10+11+12+13+17
1+2+3+4+5+6+7+9+10+11+12+14+16
1+2+3+4+5+6+7+9+10+11+13+14+15
1+2+3+4+5+6+8+9+10+11+12+13+16
1+2+3+4+5+6+8+9+10+11+12+14+15
1+2+3+4+5+7+8+9+10+11+12+13+15
1+2+3+4+6+7+8+9+10+11+12+13+14
Start Time: 2006-9-5 10:53:24
End Time: 2006-9-5 10:58:39
Total Time: 00:05:14.3906250
Total Count: 444792

如果不输出式子,结果如下:
Start Time: 2006-9-5 11:01:13
End Time: 2006-9-5 11:01:14
Total Time: 00:00:01.8750000
Total Count: 444792

完整代码如下:
/**////jailusd@hotmail.com
///2006-09-05


using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;


namespace OneToHundred
{
class Program
{
static ArrayList alFormula = new ArrayList();
static string strTempFormula;

static void Main(string[] args)
{
DateTime dtStart = DateTime.Now;

AddFormula("",1,100);

for (int i = 0; i < alFormula.Count; i++)
{
string strTemp = alFormula[i].ToString();
string[] str = strTemp.Split("+".ToCharArray());

strTemp = strTemp.Substring(0, strTemp.Length - str[str.Length - 1].ToString().Length);

AddFormula(strTemp, int.Parse(str[str.Length - 2]) + 1, int.Parse(str[str.Length - 1]));
}

DateTime dtEnd = DateTime.Now;

TimeSpan ts = DateTime.Now.Subtract(dtStart);
double count= ts.TotalMilliseconds;

Console.WriteLine("Start Time:\t" + dtStart);
Console.WriteLine("End Time:\t" + dtEnd);
Console.WriteLine("Total Time:\t" + ts);
Console.WriteLine("Total Count:\t" + alFormula.Count);
Console.ReadLine();
}

static void AddFormula(string Formual,int Start, int End)
{
int intTemp = (int)Math.Round((double)(End / 2));

if (End % 2 != 0)
{
intTemp += 1;
}

for (int i = Start; i < intTemp; i++)
{
strTempFormula = Formual + i.ToString() + "+" + (End - i).ToString();
//Console.WriteLine(strTempFormula); //显示每个满足条件的式子
alFormula.Add(strTempFormula);
}
}
}
}
Dearsoul 2006-09-04
  • 打赏
  • 举报
回复
感谢各位,特别是noahfang() ,LANXUEFEI(蓝血)
两位的思路不错,这种算法,运用很广。
希望大家都学习一下。
阿牛138588 2006-09-03
  • 打赏
  • 举报
回复
求100个数之和的都是猪,睁眼瞎的猪。
有觉得我能做,不过费时间,不做了。
daishengs 2006-09-02
  • 打赏
  • 举报
回复
我也觉得用回溯算法有可能好点。
天涯倦客 2006-09-02
  • 打赏
  • 举报
回复
这种帖子。。。。
hangge 2006-09-02
  • 打赏
  • 举报
回复
能不能用C#写一个呢
theNull 2006-09-02
  • 打赏
  • 举报
回复
flysky198() 的代码明显牛头不对马嘴,要求"数字不能重复"。
众多高人说n*(n-1)/2,恕我愚昧,看半天不知所云,,,

愿出100分赏予利用n*(n-1)/2给出完全代码者
bitmny_dot_com 2006-09-02
  • 打赏
  • 举报
回复
不好意思还有一个地方错了,

回溯过程的(2),指针也得左移一位
bitmny_dot_com 2006-09-02
  • 打赏
  • 举报
回复
有一地方搞错了

初始化: work[0] = 100;
bitmny_dot_com 2006-09-02
  • 打赏
  • 举报
回复
好像只有“solsolsol(秋水萧萧)”的想法是对的吧,用试探回溯的方法可以解出:

初始化:int work[100] = {0};
int ptr = 0;

试探过程:当前指针位置的数减一,加到后面,指针右移一位,如果当前位置的数比前面的大,继
续试探,否则生成了一个新的组合,这时若当前的数大于1,继续试探生成新的组
合,否则转到回溯过程;

回溯过程:(1)如果当前指针前面的数大于1,则指针左移一位,重新开始试探过程;
(2)否则,当前指针位置的数加到前面,当前位置置0,返回(1)的判断。

100
99 + 1
98 + 2
98 + 1 + 1
97 + 3
97 + 2 + 1
97 + 1 + 1 + 1
96 + 4
96 + 3 + 1
96 + 2 + 2
96 + 2 + 1 + 1
96 + 1 + 1 + 1 + 1
95 + 5
95 + 4 + 1
95 + 3 + 2
95 + 3 + 1 + 1
95 + 2 + 2 + 1
......
lw1a2 2006-09-02
  • 打赏
  • 举报
回复
那些写5050的,你们以为是求和吗,搞笑

这是典型的回溯遍历二叉树
LANXUEFEI 2006-09-02
  • 打赏
  • 举报
回复
To 楼上
是求和为100的所有组合如
100=1+99
100=2+98
。。。
而不是求1到100的和
tghost333 2006-09-02
  • 打赏
  • 举报
回复
最简单的算法应该是先确定都可以使用什么数字吧,先用100减资源数组(可以利用的数字)里的数,递归,直到是零为止.等待高手的高效算法.
duanwei 2006-09-02
  • 打赏
  • 举报
回复
n*(n-1)/2
LANXUEFEI 2006-09-02
  • 打赏
  • 举报
回复
代码稍作一下优化:
//总计所有算法
private void allArraySum(ref long sum,int start,int end)
{
int tempEnd;
int _end;

if((end % 2)==0)
_end=end/2-1;
else
_end=end/2;

sum=sum+_end-start;

for(int i=start+1;i<=_end;i++)
{
tempEnd= end - i;

if(tempEnd>2*(i+1))
{
allArraySum(ref sum, i, tempEnd);
}
}

}

//列举出所有的算法组合以及总计所有算法
private void printAddArray(ref long sum,string lastArray,int start,int end)
{
string tempArray;
int tempEnd;
int _end;

if((end % 2)==0)
_end=end/2-1;
else
_end=end/2;

for(int i=start+1;i<=_end;i++)
{
tempEnd= end - i;
System.Console.WriteLine(lastArray + i + "+" + tempEnd);
sum++;
if(tempEnd>2*(i+1))
{
tempArray = lastArray + i + "+";
printAddArray(ref sum,tempArray, i, tempEnd);
}
}
}
Koala_sea 2006-09-02
  • 打赏
  • 举报
回复
n*(n-1)/2
LANXUEFEI 2006-09-02
  • 打赏
  • 举报
回复
郁闷,昨天晚上一直发不上去
LANXUEFEI 2006-09-02
  • 打赏
  • 举报
回复
答案:所有算法共计:444792
代码如下:
//其实只需要调用allArraySum方法即可得到答案,速度很快
//printAddArray是为了列举出所有算法组合,速度较慢

//总计所有算法
private void allArraySum(ref long sum,int start,int end)
{
int tempEnd;
int _end;

if((end % 2)==0)
_end=end/2-1;
else
_end=end/2;

sum=sum+_end-start;

for(int i=start+1;i<=_end;i++)
{
tempEnd= end - i;

if((tempEnd-i-1)>i)
{
allArraySum(ref sum, i, tempEnd);
}
}

}

//列举出所有的算法组合以及总计所有算法
private void printAddArray(ref long sum,string lastArray,int start,int end)
{
string tempArray;
int tempEnd;
int _end;

if((end % 2)==0)
_end=end/2-1;
else
_end=end/2;

for(int i=start+1;i<=_end;i++)
{
tempEnd= end - i;
System.Console.WriteLine(lastArray + i + "+" + tempEnd);
sum++;
if((tempEnd-i-1)>i)
{
tempArray = lastArray + i + "+";
printAddArray(ref sum,tempArray, i, tempEnd);
}
}
}

//测试以上算法
private void button1_Click(object sender, System.EventArgs e)
{
long _sum=0;
printAddArray(ref _sum,"",0,100);
System.Console.WriteLine("全部的组合共计:"+_sum);
}

private void button2_Click(object sender, System.EventArgs e)
{
long _sum=0;
allArraySum(ref _sum,0,100);
System.Console.WriteLine("全部的组合共计:"+_sum);
MessageBox.Show(_sum.ToString());

}

button2_Click运行结果:
全部的组合共计:444792
button1_Click运行结果:
1+99
1+2+97
1+2+3+94
1+2+3+4+90
1+2+3+4+5+85
1+2+3+4+5+6+79
1+2+3+4+5+6+7+72
1+2+3+4+5+6+7+8+64
1+2+3+4+5+6+7+8+9+55
1+2+3+4+5+6+7+8+9+10+45
1+2+3+4+5+6+7+8+9+10+11+34
1+2+3+4+5+6+7+8+9+10+11+12+22
1+2+3+4+5+6+7+8+9+10+11+13+21
1+2+3+4+5+6+7+8+9+10+11+14+20
1+2+3+4+5+6+7+8+9+10+11+15+19
1+2+3+4+5+6+7+8+9+10+11+16+18
1+2+3+4+5+6+7+8+9+10+12+33
1+2+3+4+5+6+7+8+9+10+12+13+20
1+2+3+4+5+6+7+8+9+10+12+14+19
1+2+3+4+5+6+7+8+9+10+12+15+18
1+2+3+4+5+6+7+8+9+10+12+16+17
1+2+3+4+5+6+7+8+9+10+13+32
1+2+3+4+5+6+7+8+9+10+13+14+18
1+2+3+4+5+6+7+8+9+10+13+15+17
1+2+3+4+5+6+7+8+9+10+14+31
1+2+3+4+5+6+7+8+9+10+14+15+16
1+2+3+4+5+6+7+8+9+10+15+30
1+2+3+4+5+6+7+8+9+10+16+29
1+2+3+4+5+6+7+8+9+10+17+28
1+2+3+4+5+6+7+8+9+10+18+27
1+2+3+4+5+6+7+8+9+10+19+26
1+2+3+4+5+6+7+8+9+10+20+25
1+2+3+4+5+6+7+8+9+10+21+24
1+2+3+4+5+6+7+8+9+10+22+23
1+2+3+4+5+6+7+8+9+11+44
1+2+3+4+5+6+7+8+9+11+12+32
1+2+3+4+5+6+7+8+9+11+12+13+19
1+2+3+4+5+6+7+8+9+11+12+14+18
。。。。。
29+31+40
29+32+39
29+33+38
29+34+37
29+35+36
30+70
30+31+39
30+32+38
30+33+37
30+34+36
31+69
31+32+37
31+33+36
31+34+35
32+68
32+33+35
33+67
34+66
35+65
36+64
37+63
38+62
39+61
40+60
41+59
42+58
43+57
44+56
45+55
46+54
47+53
48+52
49+51
全部的组合共计:444792

有兴趣的朋友可以把参数改小点测试:
如列举出和为10的所有算法:
long _sum=0;
printAddArray(ref _sum,"",0,10);
System.Console.WriteLine("全部的组合共计:"+_sum);
总计和为10的所有算法:
long _sum=0;
allArraySum(ref _sum,0,10);
System.Console.WriteLine("全部的组合共计:"+_sum);
MessageBox.Show(_sum.ToString());
diandian82 2006-09-02
  • 打赏
  • 举报
回复
cout<<5050
加载更多回复(35)

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧