Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

Kombinatorika – zadaci

1. Ispisati sve varijacije sa ponavljanjem duzine n od elemenata 0, 1, 2.

PRIMER
ULAZ
Unesi n
3
IZLAZ
000
001
002
010
011
012
020
021
022
100
101
102
110
111
112
120
121
122
200
201
202
210
211
212
220
221
222

#include <stdio.h>
#include <stdlib.h>

void ispisi(int *x, int n)


{
int i;

for(i=0; i<n; i++)


printf("%d ", x[i]);
printf("\n");
}

void varijacije(int n, int pozicija, int *x)


{
int i;

for(i=0; i<=2; i++)


{
x[pozicija] = i;
if (n - 1 == pozicija) ispisi(x, n);
else varijacije(n, pozicija+1, x);
}
}

int main()
{
int n, *x;

printf("Unesi n\n");
scanf("%d", &n);

x = malloc(n*sizeof(int));

varijacije(n, 0, x);
return 0;
}

2. Ispisati sve permutacije od brojeva od 0 do m.


ULAZ
Unesi m
4

IZLAZ
0123
0132
0213
0231
0312
0321
1023
1032
1203
1230
1302
1320
2013
2031
2103
2130
2301
2310
3012
3021
3102
3120
3201
3210

#include <stdio.h>
#include <stdlib.h>

void ispisi(int *x, int n)


{
int i;

for(i=0; i<n; i++)


printf("%d ", x[i]);
printf("\n");
}

void permutacije(int m, int pozicija, int *x, int *y)


{
int i;

if (pozicija == m)
ispisi(x, m);
else
{
for(i=0; i<m; i++)
{
if (!y[i])
{
y[i] = 1;
x[pozicija] = i;
permutacije(m, pozicija+1, x, y);
y[i] = 0;
}
}
}
}

int main()
{
int m, *x, *y, i;

printf("Unesi m\n");
scanf("%d", &m);

x = malloc(m*sizeof(int));
y = malloc(m*sizeof(int));

for(i=0; i<m; i++)


y[i] = 0;
permutacije(m, 0, x, y);
return 0;
}

3. Generisati sve leksokografski uređene permutacije za dati niz elemenata celih brojeva koji se učitava sa
standardnog ulaza. Svaku leksikografski uređenu permutaciju ispisati u zasebnom redu.
ULAZ
4
8567
IZLAZ
8567
8576
8657
8675
8756
8765

ULAZ
4
4312
IZLAZ
4312
4321

#include <algorithm>
#include <cstdio>
using namespace std;

#define NMAX 10

int main() {
int n, i, a[NMAX];
scanf("%d", &n);
for (i=0;i<n;i++) scanf("%d", &a[i]);

do {
for (i=0;i<n-1;i++) printf("%d ", a[i]);
printf("%d\n", a[n-1]);
} while(next_permutation(a, a+n));
return 0;
}

4. Formirati sve moguce brojeve od cifara 1, 2 i 3 tako da se ove cifre ponajvljaju redom p, q i r puta.

Unesi n
5
Unesi p, q i r
122

12233
12323
12332
13223
13232
13322
21233
21323
21332
22133
22313
22331
23123
23132
23213
23231
23312
23321
31223
31232
31322
32123
32132
32213
32231
32312
32321
33122
33212
33221

#include <stdio.h>
#include <stdlib.h>

void ispisi(int *x, int n)


{
int i;

for(i=0; i<n; i++)


printf("%d ", x[i]);
printf("\n");
}

void varijacije(int n, int pozicija, int *x, int p, int q, int r)


{
if (p!=0)
{
x[pozicija] = 1;
if (n - 1 == pozicija) ispisi(x, n);
else varijacije(n, pozicija+1, x, p-1, q, r);
}
if (q!=0)
{
x[pozicija] = 2;
if (n - 1 == pozicija) ispisi(x, n);
else varijacije(n, pozicija+1, x, p, q-1, r);
}
if (r!=0)
{
x[pozicija] = 3;
if (n - 1 == pozicija) ispisi(x, n);
else varijacije(n, pozicija+1, x, p, q, r-1);
}

int main()
{
int n, *x, p, q, r;

printf("Unesi n\n"); //p+q+r=n


scanf("%d", &n);

printf("Unesi p, q i r\n");
scanf("%d%d%d", &p, &q, &r);

x = malloc(n*sizeof(int));

varijacije(n, 0, x, p, q, r);
}
5. Napisati program koji za dati prirodan broj n ispisuje sva njegova razbijanja na sumu prirodnih brojeva (koji ne
moraju biti razliciti).

ULAZ
Unesi broj
7

IZLAZ
7
61
52
511
43
421
4111
331
322
3211
31111
2221
22111
211111
1111111

#include <stdio.h>

void ispisi(int *x, int n)


{
int i;

for(i=0; i<n; i++)


printf("%d ", x[i]);
printf("\n");
}

void Rastavi(int n, int pos, int* x)


{
int k;
for(k=n; k>=1; k--)
{
if (k==n)
{
x[pos] = k;
if (pos > 0)
{
if (k <= x[pos-1]) //ova selekcija se koristi da se proveri da li je
//prethodni sabirak veci od sledeceg, da se ne bi ispisivali i 3+4 i 4+3 u slucaju n=7
ispisi(x, pos+1);
}
else ispisi(x, pos+1);
}
else
{
x[pos] = k;
if (pos > 0)
{
if (k <= x[pos-1])
Rastavi(n-k, pos+1, x);;
}
else Rastavi(n-k, pos+1, x);;
}
}
}

int main()
{
int n;
int x[100];

printf("Unesi broj\n");
scanf("%d", &n);

Rastavi(n, 0, x);
return 0;
}

6.
Date su terazije sa dva tasa i n tegova čije su mase a1, a2, …, an. Postavljamo svaki od datih tegova na terazije, jedan
za drugim, tako da u svakom momentu levi tas nije nikad teži od desnog tasa. U svakom koraku, biramo jedan teg
koji još nije postavljen na terazije, i smeštamo ga ili na levi tas ili na desni tas. Ponavljamo ove korake sve dok ne
upotrebimo sve tegove. Napišite program koji izračunava broj načina na koji možemo to uraditi.
Ulaz
U prvom redu standardnog ulaza dat je ceo broj n (0 < n < 10). U drugom redu se nalazi n celih brojeva: a1,
a2, …, an (0 < a1, a2, …, an < 1000).
Izlaz
Vaš program mora da ispiše jedan broj na standardni izlaz – zahtevani broj načina.
Primer
Ulaz
3
124
Izlaz
15
Rešenje:
Zadatak može da se reši pronalaženjem svih mogućnosti za postavljanje tegova pod uslovima opisanim u formulaciji
zadataka. Stoga, generišemo sve permutacija brojeva a1, a2, ... Za svaku takvu permutaciju pokušavamo da stavi
drugu težinu na levi ili desni tas, uz proveru da li ukupne težine na levom tasu nisu veće nego sa desne
strane.Predloženo rešenje je da se koristiti rekurzivna realizacija traganja tegova.

#include<iostream>
#include<algorithm>
using namespace std;

int a[10], n, ans = 0, lpan, rpan;

void set(int num)


{
if(num == n)
{
ans++;
return;
}
if (lpan + a[num] <= rpan)
{
lpan += a[num];
set(num + 1);
lpan -= a[num];
}
rpan += a[num];
set(num + 1);
rpan -= a[num];
}

int main()
{
cin >> n;
for(int i=0; i<n; i++)
cin >> a[i];
sort(a, a+n);
do
{
lpan=0; rpan=0;
set(0);

}while(next_permutation(a,a+n));
cout << ans << endl;
return 0;
}

You might also like