作为我的“算法设计和分析”课程的一项作业,我被要求使用贪婪的方法来确定进行更改所需的最小硬币数量。我想出了这种直观的方法:
#include<stdio.h>
#include<stdlib.h>
int main(){
int hundreds=0,tens=0,ones=0,sum=0;
printf("Enter a sum of money in range 1 to 999\n");
scanf("%d",&sum);
while(sum!=0) {
if (sum<10&&sum>=1){
ones=sum/1;
sum-=ones;
}
else if(sum>=10&&sum<100){
tens=sum/10;
sum-=tens*10;
}
else if(sum>=100&&sum<=999){
hundreds=sum/100;
sum-=hundreds*100;
}
else{
printf("Error");
exit(0);
}
}
printf("%d $100, %d $10, %d $1",hundreds,tens,ones);
return 0;
}
这种方法贪婪吗? 如何证明程序正确并使用贪婪方法?
答案 0 :(得分:4)
这确实是贪婪的方法,但是您需要颠倒if-then-else的顺序。通常,贪婪表示当前要消耗的最大数量。
您需要首先检查最大的硬币。不需要while循环。
if(sum>=100) {
hundreds=sum/100;
sum-=hundreds*100;
}
if(sum>=10){
tens=sum/10;
sum-=tens*10;
}
ones = sum;
答案 1 :(得分:1)
您的代码不够贪婪,因为它可能更糟:
#include<stdio.h>
#include<stdlib.h>
int main(){
int hundreds=0,tens=0,ones=0,sum=0;
printf("Enter a sum of money in range 1 to 999\n");
if ((scanf("%d",&sum) == 1) && (sum >= 1) && (sum <= 999)) {
while(sum!=0) {
if (sum<10&&sum>=1){
ones += 1;
sum -= 1;
}
else if(sum>=10&&sum<100){
tens += 1;
sum -= 10;
}
else if(sum>=100&&sum<=999){
hundreds += 1;
sum -= 100;
}
else{ /* impossible case in fact */
printf("Error");
exit(0);
}
}
printf("%d $100, %d $10, %d $1\n",hundreds,tens,ones);
}
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra g.c
pi@raspberrypi:/tmp $ ./a.out
Enter a sum of money in range 1 to 999
997
9 $100, 9 $10, 7 $1
我如何证明程序正确
一种证明代码正确的(贪婪)方法是使用残酷的力量检查从1到999的结果:
#include<stdio.h>
#include<stdlib.h>
int main(){
int n;
for (n = 1; n <= 999; ++n) {
/* the algo */
int hundreds=0,tens=0,ones=0, sum = n;
while(sum!=0) {
if (sum<10&&sum>=1){
ones += 1;
sum -= 1;
}
else if(sum>=10&&sum<100){
tens += 1;
sum -= 10;
}
else if(sum>=100&&sum<=999){
hundreds += 1;
sum -= 100;
}
else{ /* impossible case in fact */
printf("Error");
exit(0);
}
}
/* check */
if ((hundreds*100 + tens*10 + ones) != n) {
printf("error for %d : %d $100, %d $10, %d $1\n",n, hundreds,tens,ones);
exit(0);
}
}
puts("all ok");
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra g.c
pi@raspberrypi:/tmp $ ./a.out
all ok
答案 2 :(得分:0)
以下建议的代码:
现在,建议的代码:
#include <stdio.h>
int main( void )
{
int sum;
do
{
printf("Enter a sum of money in range 1 to 999\n");
if( scanf("%d",&sum) != 1)
{
fprintf( stderr, "scanf failed\n");
return -1;
}
} while( sum<0 || sum>999 );
int hundreds = sum/100;
sum = sum % 100;
int tens = sum/10;
sum = sum % 10;
int ones = sum;
printf("%d $100, %d $10, %d $1\n",hundreds,tens,ones);
}
建议的代码将忽略50美元,20美元,5美元和2美元的美国账单。