#include #include #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define prunik(xl, xp, yl, yp) (((xl <= yl && xp > yl) || (yl <= xl && yp > xl))?1:0) // je prunik dvou intervalu neprazdny? typedef struct skvrna { // udaje o skrvne int levy, pravy, horni, dolni; // okraje skvrny int barva; struct skvrna *dalsi; // ukazatel na dalsi skrvnu ve spojovem seznamu } SKVRNA; void rozpad(SKVRNA *nova, SKVRNA *stara) { // rozpadne starou skvrnu a misto ni vytvori spojovy seznam rozpadlych casti SKVRNA *seznam, *konec; // spojovy seznam vzniklych casti; konec seznamu if (!prunik(stara->levy, stara->pravy, nova->levy, nova->pravy) || !prunik(stara->dolni, stara->horni, nova->dolni, nova->horni)) return; // pokud se skvrny neprekryvaji, nemame co delat seznam = konec = (SKVRNA *)malloc(sizeof(SKVRNA)); // na zacatek seznamu dame starou skvrnu *seznam = *stara; seznam->dalsi = NULL; if (stara->horni > nova->horni) { // urizneme horni kus konec->dalsi = (SKVRNA *)malloc(sizeof(SKVRNA)); konec = konec->dalsi; konec->horni = stara->horni; konec->dolni = nova->horni; konec->levy = stara->levy; konec->pravy = stara->pravy; konec->barva = stara->barva; konec->dalsi = NULL; } if (stara->dolni < nova->dolni) { // urizneme spodek konec->dalsi = (SKVRNA *)malloc(sizeof(SKVRNA)); konec = konec->dalsi; konec->horni = nova->dolni; konec->dolni = stara->dolni; konec->levy = stara->levy; konec->pravy = stara->pravy; konec->barva = stara->barva; konec->dalsi = NULL; } if (stara->levy < nova->levy) { // urizneme levy kus konec->dalsi = (SKVRNA *)malloc(sizeof(SKVRNA)); konec = konec->dalsi; konec->horni = min(nova->horni, stara->horni); konec->dolni = max(nova->dolni, stara->dolni); konec->levy = stara->levy; konec->pravy = nova->levy; konec->barva = stara->barva; konec->dalsi = NULL; } if (stara->pravy > nova->pravy) { // urizneme pravy kus konec->dalsi = (SKVRNA *)malloc(sizeof(SKVRNA)); konec = konec->dalsi; konec->horni = min(nova->horni, stara->horni); konec->dolni = max(nova->dolni, stara->dolni); konec->levy = nova->pravy; konec->pravy = stara->pravy; konec->barva = stara->barva; konec->dalsi = NULL; } konec->dalsi = stara->dalsi; // napojime seznam na puvodni pokracovani *stara = *(seznam->dalsi); // a vynechame rozpadnutou skvrnu } int main(void) { int N; // pocet skvrn int W, H; // rozmery tricka int *plocha; // plochy jednotlivych barev SKVRNA *skvrny = NULL; // spojovy seznam skvrn SKVRNA *skvrny_kon; // ukazatel na konec seznamu scanf("%d%d%d", &N, &W, &H); plocha = (int *)malloc((N+1)*sizeof(int)); for (int i=0; idalsi = (SKVRNA *)malloc(sizeof(SKVRNA)); skvrny_kon = skvrny_kon->dalsi; } scanf("%d%d%d%d%d", &skvrny_kon->levy, &skvrny_kon->dolni, &skvrny_kon->pravy, &skvrny_kon->horni, &skvrny_kon->barva); skvrny_kon->dalsi = NULL; // projdeme seznam skvrn a provedeme rozpady for (SKVRNA *stara = skvrny; stara != skvrny_kon; stara = stara->dalsi) { rozpad(skvrny_kon, stara); } } for (int i=1; i<=N; i++) plocha[i] = 0; for (SKVRNA *s = skvrny; s != NULL; s = s->dalsi) plocha[s->barva] += (s->pravy-s->levy) * (s->horni-s->dolni); int ciste = W*H; for (int i=1; i<=N; i++) { printf("Barva %d zabira na tricku %d jednotek plochy.\n", i, plocha[i]); ciste -= plocha[i]; } printf("Cisteho tricka zustalo %d jednotek.\n", ciste); return 0; }