Пример 1



/* Задача о размене монеты:

 * Поиск всех возможных коэффициентов a0 .. an разложения числа  S

 * в виде

 *      S = a0 * c0 + a1 * c1 + ... + an * cn

 * где веса c0 .. cn заданы заранее и упорядочены.

 * Веса и коэффициенты неотрицательны (ai >= 0, ci >= 0).

 */

#include <stdio.h>

/* Достоинства разменных монет (веса ci) */

int cost[] = {

	1, 2, 3, 5, 10, 15, 20, 50, 100, 300, 500  /* копеек */

};

#define N       (sizeof cost / sizeof(int))

int count[ N ];         /* число монет данного типа (коэффициенты ai) */

long nvar;              /* число вариантов */

main( ac, av ) char *av[];

{

    int coin;

    if( ac == 1 ){

	fprintf( stderr, "Укажите, какую монету разменивать: %s число\n",

		av[0] );

	exit(1);

    }

    coin = atoi( av[1] );

    printf( "          Таблица разменов монеты %d коп.\n", coin );

printf( " Каждый столбец содержит количество монет указанного достоинства.\n" );

printf( "-------------------------------------------------------------------\n" );

printf( "| 5р. | 3р. | 1р. | 50к.| 20к.| 15к.| 10к.|  5к.|  3к.|  2к.|  1к.|\n" );

printf( "-------------------------------------------------------------------\n" );

    change( N-1, coin );

printf( "-------------------------------------------------------------------\n" );

    printf( "Всего %ld вариантов\n", nvar );

}

/* рекурсивный размен */

change( maxcoin, sum )

	int sum;        /* монета, которую меняем */

	int maxcoin;    /* индекс по массиву cost[] монеты максимального

			 * достоинства, допустимой в данном размене.

			 */

{

	register i;

	if( sum == 0 ){  /* вся сумма разменяна */

		/* распечатать очередной вариант */

		putchar( '|' );

		for( i = N-1 ; i >= 0 ; i-- )

			if( count[i] )

			    printf(" %3d |", count[ i ] );

			else

			    printf("     |" );

		putchar( '\n' );

		nvar++;

		return;

	}

	if( sum >= cost [ maxcoin ] ){

	    /* если можно выдать монету достоинством cost[maxcoin] ,

	     * то выдать ее:

	     */

	    count[ maxcoin ] ++;   /* посчитали выданную монету */

       /* размениваем остаток суммы :

	* Первый аргумент - может быть можно дать еще одну такую монету ?

	* Второй аргумент - общая сумма убавилась на одну монету cost[maxcoin].

	*/

	    change( maxcoin, sum - cost[maxcoin] );

	    count[ maxcoin ] --;   /* ... Теперь попробуем иной вариант ... */

	}

	/* попробовать размен более мелкими монетами */

	if( maxcoin )

		change( maxcoin-1, sum );

}

[Назад][Содержание][Вперед]

Используются технологии uCoz