Termlərə Parçalanma#2390

Termlərə Parçalanma (Həll təhlili)

Qoy n = x_1 + x_2 + ... + x_k — sayını natural toplananlar şəklində təsviri olsun. Məsələ şərtindən götürsək, təsvirin hər hansı bir yığıcıları bu bərabərsizliyə uyğun olmalıdır:

x_1 \ge x_2 \ge ... \ge x_k

Birinci yığıcı x_1 1-dən -ə qədər olan qiymətləri ala bilər, və hər bir növbəti x_i~(2 \le i \le k) — x_{i-1}-dən böyük olmayan qiymətlər ala bilər.

Təsvirlərin yaradılma prosedurlarının rekursiv mahiyyəti belədir: əgər sayının təsvirində birinci yığıcı olaraq x_1~(x_1 \le n) seçilibsə, onda növbəti yığıcı n - x_1 sayının yaradılmasıdır ki, bu da x_1-dən böyük olmayan yığıcıları ehtiva edir.

Alqoritmin tətbiqi

Arraydə , sayını əks etdirən yığıcıları yaradacağıq.

int x[50];

f funksiyası sayını təsvir edən yığıcıları generasiya edir və üç arqument alır:

void f(int pos, int max, int n)
{

Əgər dəyəri sıfıra bərabər olarsa, bu, təsvirin tamamlandığı və cari arrayi növbəti təsviri təmsil etdiyi deməkdir. Bu halda arrayi çıxış olaraq veririk.

  if (n == 0)
  {
    for (int i = 0; i < pos; i++) 
      printf("%d ", x[i]);
    printf("\n");
    return;
  }

arrayində mövqeyində 1-dən min(max, n)-ə qədər olan hər hansı bir ədəd yerləşə bilər.

  for (int i = 1; i <= min(max, n); i++)
  {
    x[pos] = i;
    f(pos + 1, i, n - i);
  }
}

Proqramın əsas hissəsi. Giriş olaraq dəyərini oxuyur və həmin sayın bütün mümkün təsvirlərini generasiya edən funksiyanı işə salırıq.

scanf("%d",&n);
f(0,n,n);