练手程序2006-9-7

 13:01 2006-9-7:昨天下午的时候跟jailu聊天的时候说了这个题:
从1到100,100个数字相加,和为100的算法,可以1位,2位,3位等,不限位数相加,数字不能重复,可以有多少种算法,并把代码贴出;
可以这样:
        1 + 99;
        2 + 98;
也可以这样:
        1 + 2 + 97;
更可以这样:
        1 + 2 + 3 + 5 + 7 + 82;
jailu说写个汇编看看运行效率如何,于是我就写,初时想了好久好久,都没有什么可行的方法,主要是心静不下来,结果想到晚上还是没有结果,于是今天早上去上自习,想了一会,加上昨天的一些思路,很快就出结果了。而且程序很短,郁闷,jailu说他用了10min写的,而我却用了6~7 h

13:18 2006-9-7:目前运行结果正确:444792,耗时10ms,效率是jailu的100倍,因为局部变量的使用,我的数据存放最多为:50*13*13*4=33800 B 约33K,而jailu的使用量:每个结果平均最少需要14个B的空间,也就是5个值4个加号,即共计最少占用14*444792=6MB!

 

;http://www.cnblogs.com/jailu/archive/2006/09/05/494832.html
;http://community.youkuaiyun.com/Expert/topic/4992/4992453.xml?temp=.9884455

.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:masm32macrosMACROS.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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值