MIPS+贪心 数列极差

贪心算法-数列极差问题
【题目描述】 
 在黑板上写了N个正整数做成的一个数列,进行如下操作:每一次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的max,最小的为min,则该数列的极差定义为M=max-min。
编程任务:对于给定的数列,编程计算出极差M。
输入输出样例:
输入:                    
4
2 1 4 3

输出:
13

这是贪心算法问题,不断对最小的两个数操作就能得到最大值,不断对最大的两个数操作就能得到最小值。

C++代码:
#include<iostream>
#include<algorithm>
#define MAX 1050
using namespace std;
bool cmp(const int a,const int b)
{
return a>b;
}
int main()
{
int n,i,max,min;
int a[MAX];
int b[MAX];
while(cin>>n){
    i=n;
    while(i>0){
        cin>>a[n-i];
        i--;
    }
    int blength=n;
    for(i=0;i<n;i++)
        b[i]=a[i];
    while(n>1){
        sort(a,a+n);
        a[0]=a[0]*a[1]+1;
        for(i=1;i<n-1;i++)
            a[i]=a[i+1];
        n--;
    }
    while(blength>1){
        sort(b,b+blength,cmp);
        b[0]=b[0]*b[1]+1;
        for(i=1;i<blength-1;i++)
            b[i]=b[i+1];
        blength--;
    }
    max=a[0];
    min=b[0];
    cout<<max-min<<endl;                
}   
} 


汇编写了两个while循环,调用了两个排序,所以写得比较乱:
.data 
arrayA:.space 1024
arrayB:.space 1024
.text
li $v0,5
syscall
move $t0,$v0 #use $t0 as n
move $t1,$0 #use $t1 as i
forinput:
slt $t2,$t1,$t0
beq $t2,$0,endinput
li $v0,5
syscall
sll $t2,$t1,2
sw $v0,0($t2)
sw $v0,1024($t2)
addi $t1,$t1,1
j forinput
endinput:
move $t6,$t0
while1:
    addi $t4,$0,1
    slt $t4,$t4,$t6
    beq $t4,$0,breakwhile1
    move $a1,$t6
    addi $a0,$0,0
    jal sort1
    addi $t2,$0,0
    sll $t2,$t2,2
    lw $t3,0($t2)
    lw $t5,4($t2)
    mult $t3,$t5
    mflo $t3
    addi $t3,$t3,1
    sw $t3,0($0)
    li $t1,1
    subi $s2,$t6,1
    fordelete1:
    slt $t4,$t1,$s2
    beq $t4,$0,endfordelete1
    sll $s3,$t1,2
    lw $s4,0($s3) #a[i]
    lw $s5,4($s3) #a[i+1]
    sw $s5,0($s3)
    addi $t1,$t1,1
    j fordelete1
    endfordelete1:
    subi $t6,$t6,1
    j while1
    breakwhile1:
    lw $t9,0($0) #max
    while2:
    addi $t4,$0,1
    slt $t4,$t4,$t0
    beq $t4,$0,breakwhile2
    move $a1,$t0
    addi $a0,$0,1024
    jal sort2
    addi $t2,$0,0
    sll $t2,$t2,2
    lw $t3,1024($t2)
    lw $t5,1028($t2)
    mult $t3,$t5
    mflo $t3
    addi $t3,$t3,1
    sw $t3,1024($0)
    li $t1,1
    subi $s2,$t0,1
    fordelete2:
    slt $t4,$t1,$s2
    beq $t4,$0,endfordelete2
    sll $s3,$t1,2
    lw $s4,1024($s3) #a[i]
    lw $s5,1028($s3) #a[i+1]
    sw $s5,1024($s3)
    addi $t1,$t1,1
    j fordelete2
    endfordelete2:
    subi $t0,$t0,1
    j while2
breakwhile2:
    lw $s7,1024($0) #min
    j end

sort1:
move $t2,$a0 #$a0 表示首地址
move $t3,$a1 #$a1 表示n
subi $t5,$t3,1 #use $t5 as n-1
addi $t1,$0,0 #use $t1 as i
fori:
slt $t4,$t1,$t5
beq $t4,$0,endfori
move $s0,$t1 #use $s0 as index
addi $s1,$t1,1 #j=i+1
forj:
    slt $t4,$s1,$t3
    beq $t4,$0,endforj
    sll $s2,$s0,2
    add $s2,$s2,$t2
    lw $s5,0($s2) #a[index]
    sll $s3,$s1,2
    add $s3,$s3,$t2
    lw $s6,0($s3) #a[j]
    slt $t4,$s5,$s6
    beq $t4,0,swap
    addi $s1,$s1,1
    j forj
    swap:
    move $s0,$s1
    addi $s1,$s1,1
    j forj
endforj:
    sll $s2,$t1,2
    add $s2,$s2,$t2
    lw $s5,0($s2) #get a[i]
    sll $s3,$s0,2
    add $s3,$s3,$t2
    lw $s6,0($s3)
    sw $s5,0($s3)
    sw $s6,0($s2)
    addi $t1,$t1,1
    j fori
endfori:
jr $31
sort2:
move $t2,$a0 #$a0 表示首地址
move $t3,$a1 #$a1 表示n
subi $t5,$t3,1 #use $t5 as n-1
addi $t1,$0,0 #use $t1 as i
fori2:
slt $t4,$t1,$t5
beq $t4,$0,endfori2
move $s0,$t1 #use $s0 as index
addi $s1,$t1,1 #j=i+1
forj2:
    slt $t4,$s1,$t3
    beq $t4,$0,endforj2
    sll $s2,$s0,2
    add $s2,$s2,$t2
    lw $s5,($s2) #a[index]
    sll $s3,$s1,2
    add $s3,$s3,$t2
    lw $s6,0($s3) #a[j]
    slt $t4,$s6,$s5
    beq $t4,0,swap2
    addi $s1,$s1,1
    j forj2
    swap2:
    move $s0,$s1
    addi $s1,$s1,1
    j forj2
endforj2:
    sll $s2,$t1,2
    add $s2,$s2,$t2
    lw $s5,0($s2) #get a[i]
    sll $s3,$s0,2
    add $s3,$s3,$t2
    lw $s6,0($s3)
    sw $s5,0($s3)
    sw $s6,0($s2)
    addi $t1,$t1,1
    j fori2
endfori2:
jr $31
end:
sub $t9,$t9,$s7
move $a0,$t9
li $v0,1
syscall
li $v0,10
syscall
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值