贪心算法-数列极差问题
【题目描述】
在黑板上写了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
MIPS+贪心 数列极差
最新推荐文章于 2024-05-08 00:37:44 发布