Utolsó módosítás: 2008. november 14.
Itt van egy-egy megoldás az első verseny feladataira. Ezek persze nem feltétlenül a legszebb vagy legegyszerűbb megoldások.
A feladat kiírása; megoldás letöltése: z0f0.c.
#include <stdio.h> #include <stdlib.h> int main(void) { int k, last, cur; last = -1; for (k = 0; k < 14; k++) { if (1 != scanf("%d", &cur)) exit(1); if (0 != cur) last = cur; printf("%d%c", last, 13 == k ? '\n' : ' '); } return 0; }
A feladat kiírása; megoldás letöltése: z0f1.c.
#include <stdio.h> #include <stdlib.h> #include <string.h> void die(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } #define TEMPLATE_MAXLEN 10100 char template[TEMPLATE_MAXLEN]; void read_template(void) { int stop = 0; size_t pos = 0; while (!stop) { if ( TEMPLATE_MAXLEN - pos < 2 || !fgets(template + pos, TEMPLATE_MAXLEN - pos, stdin) ) die("error reading template"); if ('$' == template[pos]) stop = 1; else pos += strlen(template + pos); } } #define LINE_MAXLEN 4010 char line[LINE_MAXLEN]; int more_mail(void) { int i; if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record head"); if (1 != sscanf(line, "%d", &i)) die("error: record head has wrong format"); return i; } void process_mail(int wt) { size_t pos; size_t len; int cnt_mmark = 0; int k; for (pos = 0; '$' != template[pos]; pos++) { if ('@' == template[pos]) { pos++; if ('i' == template[pos]) { if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record body"); len = strlen(line); line[len - 1] = 0; fputs(line, stdout); } else if ('m' == template[pos] && '\n' == template[pos + 1]) { cnt_mmark++; for (k = 0; k < wt; k++) { if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record body"); fputs(line, stdout); } pos++; } else die("error: field marker has wrong format"); } else putchar(template[pos]); } if (1 != cnt_mmark) die("exactly one m marker required in the template"); } int main(void) { int wt; read_template(); while ((wt = more_mail())) process_mail(wt); return 0; }
A feladat kiírása; megoldás letöltése: z0f2.c.
#include <stdio.h> #include <stdlib.h> #include <string.h> void die(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } char mirror_char(char *key, char c) { while (key[0] && key[1]) { if (c == key[0]) return key[1]; if (c == key[1]) return key[0]; key += 2; } return c; } #define TEMPLATE_MAXHEIGHT 20 #define TEMPLATE_MAXWIDTH 20 #define STRIP_MAXWIDTH (2 + TEMPLATE_MAXWIDTH * 10) int template_height, template_width; char template[TEMPLATE_MAXHEIGHT][TEMPLATE_MAXWIDTH]; int num_copies, copy_mode, num_vert_copies, vert_copy_mode; char mirrored[TEMPLATE_MAXHEIGHT][TEMPLATE_MAXWIDTH]; char strip[TEMPLATE_MAXHEIGHT][STRIP_MAXWIDTH], strip_vert_mirrored[TEMPLATE_MAXHEIGHT][STRIP_MAXWIDTH]; void read_template(void) { char line[TEMPLATE_MAXWIDTH + 5]; int r; for (r = 0; r < template_height; r++) { if (!fgets(line, TEMPLATE_MAXWIDTH + 5, stdin)) die("eof or error reading template line"); if (template_width != strlen(line) - 1) die("template line length wrong"); memcpy(template[r], line, template_width); } } void mirror_template(void) { int r, c; for (r = 0; r < template_height; r++) { for (c = 0; c < template_width; c++) mirrored[r][c] = mirror_char("()<>[]\\/", template[r][template_width - c - 1]); } } void output_strip(void) { int row, copy; char *p; int l; char *out; for (row = 0; row < template_height; row++) { out = strip[row]; for (copy = 0; copy < num_copies; copy++) { if (0 == copy % 2 || 0 == copy_mode) { p = template[row]; l = template_width; } else if (2 == copy_mode) { p = mirrored[row] + 1; l = template_width - 1; } else { p = mirrored[row]; l = template_width; } memcpy(out, p, l); out += l; } *out++ = '\n'; *out++ = 0; } } void mirror_strip(void) { int r, c; for (r = 0; r < template_height; r++) { for (c = 0; strip[r][c]; c++) { strip_vert_mirrored[r][c] = mirror_char(",'\\/", strip[r][c]); } } } void output_all(void) { int copy, row; for (copy = 0; copy < num_vert_copies; copy++) { if (0 == copy % 2 || 0 == vert_copy_mode) { for (row = 0; row < template_height; row++) fputs(strip[row], stdout); } else if (2 == vert_copy_mode) { for (row = template_height - 2; 0 <= row; row--) fputs(strip_vert_mirrored[row], stdout); } else { for (row = template_height - 1; 0 <= row; row--) fputs(strip_vert_mirrored[row], stdout); } } } int main(void) { char line[500]; if (!fgets(line, sizeof(line), stdin)) die("error reading parameters"); if (6 != sscanf(line, "%d%d%d%d%d%d", &template_height, &template_width, &num_copies, ©_mode, &num_vert_copies, &vert_copy_mode )) die("error parsing parameters"); if ( TEMPLATE_MAXHEIGHT < template_height || template_height < 0 || TEMPLATE_MAXWIDTH < template_width || template_width < 0 || 2 < copy_mode || copy_mode < 0 ) die("invalid parameters"); read_template(); mirror_template(); output_strip(); mirror_strip(); output_all(); return 0; }
A feladat kiírása; megoldás letöltése: z0f3.c.
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int max(int x, int y) { return x < y ? y : x; } #define PLANBUF_LEN 512 #define PREC_ATOM 0 #define PREC_POWER 2 #define PREC_QUOTIENT 3 #define PREC_PRODUCT 4 #define PREC_SUM 5 #define PREC_FACTOR 6 struct plan { int width; int height; int depth; int prec; int head; const struct plan *lhs; const struct plan *rhs; } planbuf[PLANBUF_LEN]; int plancnt; void init(void) { plancnt = 0; } struct plan * allocplan(void) { struct plan *r; r = planbuf + plancnt++; if (PLANBUF_LEN < plancnt) exit(1); r->lhs = r->rhs = 0; r->prec = r->head = -1; r->width = r->height = r->depth = 32767; return r; } const struct plan * parenthisize(const struct plan *l) { struct plan *p; p = allocplan(); p->head = '('; p->lhs = l; p->width = l->width + 2; p->height = l->height; p->depth = l->depth; p->prec = PREC_ATOM; return p; } const struct plan * layout(const char **formulap) { struct plan *p; char head; const struct plan *l, *r; p = allocplan(); p->head = head = *(*formulap)++; if (isdigit(head) || islower(head)) { p->width = 1; p->height = 1; p->depth = 0; p->prec = PREC_ATOM; } else { l = layout(formulap); if ('!' == head) { if (PREC_POWER <= l->prec) l = parenthisize(l); p->width = l->width + 1; p->height = l->height; p->depth = l->depth; p->prec = PREC_ATOM; } else { r = layout(formulap); if ('^' == head) { if (PREC_POWER <= l->prec) l = parenthisize(l); p->width = l->width + r->width; p->height = l->height + r->depth + r->height; p->depth = l->depth; p->prec = PREC_POWER; } else if ('/' == head) { p->width = 2 + max(l->width, r->width); p->height = 1 + l->height + l->depth; p->depth = r->height + r->depth; p->prec = PREC_QUOTIENT; } else if ('*' == head) { if (PREC_PRODUCT < l->prec) l = parenthisize(l); if (PREC_PRODUCT <= r->prec) r = parenthisize(r); p->width = 1 + l->width + r->width; p->height = max(l->height, r->height); p->depth = max(l->depth, r->depth); p->prec = PREC_PRODUCT; } else if ('+' == head || '-' == head) { if (PREC_SUM <= r->prec) r = parenthisize(r); p->width = 3 + l->width + r->width; p->height = max(l->height, r->height); p->depth = max(l->depth, r->depth); p->prec = PREC_SUM; } else exit(1); p->rhs = r; } p->lhs = l; } return p; } #define PAPER_WIDTH 500 #define PAPER_HEIGHT 100 char paper[PAPER_HEIGHT][PAPER_WIDTH]; int box_height, box_width; void erase(const struct plan *p) { int r, c; box_height = p->height + p->depth; box_width = p->width; if (PAPER_HEIGHT < box_height || PAPER_WIDTH < box_width) exit(1); for (r = 0; r < box_height; r++) for (c = 0; c < box_width; c++) paper[r][c] = ' '; } void output(void) { int r, w, c; for (r = 0; r < box_height; r++) { w = box_width; while (' ' == paper[r][w - 1]) w--; for (c = 0; c < w; c++) putchar(paper[r][c]); putchar('\n'); } putchar('\n'); } void paint(const struct plan *p, int row, int col) { int r, c; int head; if ( row - p->height + 1 < 0 || box_height < row + p->depth || col < 0 || box_width < col + p->width ) exit(1); head = p->head; switch (head) { case '(': for (r = row - p->height + 1; r <= row + p->depth; r++) { paper[r][col] = '('; paper[r][col + p->width - 1] = ')'; } paint(p->lhs, row, 1 + col); break; case '!': paint(p->lhs, row, col); paper[row][col + p->lhs->width] = '!'; break; case '^': paint(p->lhs, row, col); paint(p->rhs, row - p->lhs->height - p->rhs->depth, col + p->lhs->width); break; case '/': for (c = col; c < col + p->width; c++) paper[row][c] = '-'; paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2); paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2); break; case '*': paint(p->lhs, row, col); paint(p->rhs, row, 1 + col + p->lhs->width); break; case '+': case '-': paint(p->lhs, row, col); paper[row][1 + col + p->lhs->width] = head; paint(p->rhs, row, 3 + col + p->lhs->width); break; default: if (isdigit(head) || islower(head)) paper[row][col] = head; else exit(1); break; } } void paint_main(const struct plan *p) { paint(p, p->height - 1, 0); } #define FORMULA_LEN 512 int main(void) { char formulabuf[FORMULA_LEN]; const struct plan *p; const char *formula; while (fgets(formulabuf, FORMULA_LEN, stdin)) { formula = formulabuf; init(); p = layout(&formula); if ('\n' != *formula) exit(1); erase(p); paint_main(p); output(); } return 0; }
A feladat kiírása; megoldás letöltése: z1f0.c.
#include <stdio.h> #include <stdlib.h> int main(void) { int k, e0, e1, sum; sum = 0; for (k = 0; k < 7; k++) { if (2 != scanf("%d%d", &e0, &e1)) exit(1); sum = sum + e0 - e1; } printf("%d\n", sum); return 0; }
A feladat kiírása; megoldás letöltése: z1f1.c.
#include <stdio.h> #include <stdlib.h> #include <string.h> void die(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } #define TEMPLATE_MAXLEN 10100 char template[TEMPLATE_MAXLEN]; void read_template(void) { int stop = 0; size_t pos = 0; while (!stop) { if ( TEMPLATE_MAXLEN - pos < 2 || !fgets(template + pos, TEMPLATE_MAXLEN - pos, stdin) ) die("error reading template"); if ('$' == template[pos]) stop = 1; else pos += strlen(template + pos); } } #define LINE_MAXLEN 4010 char line[LINE_MAXLEN]; int more_mail(void) { int i; if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record head"); if (1 != sscanf(line, "%d", &i)) die("error: record head has wrong format"); return i; } void process_mail(int weight) { size_t pos; size_t len; int state, branch; state = -1; branch = -99; for (pos = 0; '$' != template[pos]; pos++) { if ('@' == template[pos]) { pos++; if ('i' == template[pos]) { if (state || weight == branch) { if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record body"); len = strlen(line); line[len - 1] = 0; fputs(line, stdout); } } else if ('s' == template[pos]) { if (-1 != state) die("error: multiple select case markers"); state = 0; branch = 1; } else if ('c' == template[pos]) { if (0 != state) die("error: case marker outside select"); branch++; } else if ('e' == template[pos]) { if (0 != state) die("error: end select marker outside select"); state = 1; } else die("error: field marker has wrong format"); } else { if (state || weight == branch) putchar(template[pos]); } } } int main(void) { int wt; read_template(); while ((wt = more_mail())) process_mail(wt); return 0; }
A feladat kiírása; megoldás letöltése: z1f2.c.
#include <stdio.h> #include <stdlib.h> #define NUM_DAYS 60 int main(void) { int reserve1[NUM_DAYS], reserve2[NUM_DAYS]; int num_rooms1, num_rooms2, num_calls; int first, last, need1, need2; int r, d, ok; for (d = 0; d < NUM_DAYS; d++) { reserve1[d] = 0; reserve2[d] = 0; } if (3 != scanf("%d%d%d", &num_rooms1, &num_rooms2, &num_calls)) exit(1); for (r = 0; r < num_calls; r++) { if (4 != scanf("%d%d%d%d", &first, &last, &need1, &need2)) exit(1); if (first < 0 || last < first || NUM_DAYS <= last || need1 < 0 || need2 < 0) exit(1); ok = 1; for (d = first; d <= last; d++) { if (num_rooms1 < reserve1[d] + need1 || num_rooms2 < reserve2[d] + need2) ok = 0; } if (ok) { for (d = first; d <= last; d++) { reserve1[d] += need1; reserve2[d] += need2; } printf("1\n"); } else { printf("0\n"); } } return 0; }
A feladat kiírása; megoldás letöltése: z1f3.c.
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int max(int x, int y) { return x < y ? y : x; } #define PLANBUF_LEN 512 #define PREC_ATOM 0 #define PREC_POWER 2 #define PREC_QUOTIENT 3 #define PREC_PRODUCT 4 #define PREC_SUM 5 struct plan { int width; int height; int depth; int prec; int head; const struct plan *lhs; const struct plan *rhs; } planbuf[PLANBUF_LEN]; int plancnt; void init(void) { plancnt = 0; } struct plan * allocplan(void) { struct plan *r; r = planbuf + plancnt++; if (PLANBUF_LEN < plancnt) exit(1); r->lhs = r->rhs = 0; r->prec = r->head = -1; r->width = r->height = r->depth = 32767; return r; } const struct plan * parenthisize(const struct plan *l) { struct plan *p; p = allocplan(); p->head = '('; p->lhs = l; p->width = l->width + 2; p->height = l->height; p->depth = l->depth; p->prec = PREC_ATOM; return p; } const struct plan * layout(const char **formulap) { struct plan *p; char head; const struct plan *l, *r; p = allocplan(); p->head = head = *(*formulap)++; if (isdigit(head) || islower(head)) { p->width = 1; p->height = 1; p->depth = 0; p->prec = PREC_ATOM; } else { l = layout(formulap); r = layout(formulap); if ('?' == head) { p->width = 2 + max(l->width, r->width); p->height = 1 + l->height + l->depth; p->depth = r->height + r->depth; p->prec = PREC_ATOM; } else if ('^' == head) { if (PREC_POWER <= l->prec) l = parenthisize(l); p->width = l->width + r->width; p->height = l->height + r->depth + r->height; p->depth = l->depth; p->prec = PREC_POWER; } else if ('/' == head) { p->width = 2 + max(l->width, r->width); p->height = 1 + l->height + l->depth; p->depth = r->height + r->depth; p->prec = PREC_QUOTIENT; } else if ('*' == head) { if (PREC_PRODUCT < l->prec) l = parenthisize(l); if (PREC_PRODUCT <= r->prec) r = parenthisize(r); p->width = 1 + l->width + r->width; p->height = max(l->height, r->height); p->depth = max(l->depth, r->depth); p->prec = PREC_PRODUCT; } else if ('+' == head || '-' == head) { if (PREC_SUM <= r->prec) r = parenthisize(r); p->width = 3 + l->width + r->width; p->height = max(l->height, r->height); p->depth = max(l->depth, r->depth); p->prec = PREC_SUM; } else exit(1); p->lhs = l; p->rhs = r; } return p; } #define PAPER_WIDTH 500 #define PAPER_HEIGHT 100 char paper[PAPER_HEIGHT][PAPER_WIDTH]; int box_height, box_width; void erase(const struct plan *p) { int r, c; box_height = p->height + p->depth; box_width = p->width; if (PAPER_HEIGHT < box_height || PAPER_WIDTH < box_width) exit(1); for (r = 0; r < box_height; r++) for (c = 0; c < box_width; c++) paper[r][c] = ' '; } void output(void) { int r, w, c; for (r = 0; r < box_height; r++) { w = box_width; while (' ' == paper[r][w - 1]) w--; for (c = 0; c < w; c++) putchar(paper[r][c]); putchar('\n'); } putchar('\n'); } void paint(const struct plan *p, int row, int col) { int r, c; int head; if ( row - p->height + 1 < 0 || box_height < row + p->depth || col < 0 || box_width < col + p->width ) exit(1); head = p->head; switch (head) { case '(': for (r = row - p->height + 1; r <= row + p->depth; r++) { paper[r][col] = '('; paper[r][col + p->width - 1] = ')'; } paint(p->lhs, row, 1 + col); break; case '?': for (r = row - p->height + 1; r <= row + p->depth; r++) { paper[r][col] = '('; paper[r][col + p->width - 1] = ')'; } paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2); paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2); break; case '^': paint(p->lhs, row, col); paint(p->rhs, row - p->lhs->height - p->rhs->depth, col + p->lhs->width); break; case '/': for (c = col; c < col + p->width; c++) paper[row][c] = '-'; paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2); paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2); break; case '*': paint(p->lhs, row, col); paint(p->rhs, row, 1 + col + p->lhs->width); break; case '+': case '-': paint(p->lhs, row, col); paper[row][1 + col + p->lhs->width] = head; paint(p->rhs, row, 3 + col + p->lhs->width); break; default: if (isdigit(head) || islower(head)) paper[row][col] = head; else exit(1); break; } } void paint_main(const struct plan *p) { paint(p, p->height - 1, 0); } #define FORMULA_LEN 512 int main(void) { char formulabuf[FORMULA_LEN]; const struct plan *p; const char *formula; while (fgets(formulabuf, FORMULA_LEN, stdin)) { formula = formulabuf; init(); p = layout(&formula); if ('\n' != *formula) exit(1); erase(p); paint_main(p); output(); } return 0; }
A feladat kiírása; megoldás letöltése: z2f0.c.
#include <stdio.h> #include <stdlib.h> int main(void) { int k, last, cur, out; last = 0; out = 0; for (k = 0; k < 14; k++) { if (1 != scanf("%d", &cur)) exit(1); if (0 < k && cur < last) out++; last = cur; } printf("%d\n", out); return 0; }
A feladat kiírása; megoldás letöltése: z2f1.c.
#include <stdio.h> #include <stdlib.h> #include <string.h> void die(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } #define TEMPLATE_MAXLEN 10100 char template[TEMPLATE_MAXLEN]; void read_template(void) { int stop = 0; size_t pos = 0; while (!stop) { if ( TEMPLATE_MAXLEN - pos < 2 || !fgets(template + pos, TEMPLATE_MAXLEN - pos, stdin) ) die("error reading template"); if ('$' == template[pos]) stop = 1; else pos += strlen(template + pos); } } #define LINE_MAXLEN 4010 char line[LINE_MAXLEN]; int more_mail(void) { int i; if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record head"); if (1 != sscanf(line, "%d", &i)) die("error: record head has wrong format"); return i; } void process_mail(int wt) { size_t pos; size_t len; int k; for (pos = 0; '$' != template[pos]; pos++) { if ('@' == template[pos]) { pos++; if ('i' == template[pos]) { if (!fgets(line, LINE_MAXLEN, stdin)) die("error reading record body"); len = strlen(line); line[len - 1] = 0; fputs(line, stdout); } else if ('h') { for (k = 0; k < wt; k++) putchar('-'); } else die("error: field marker has wrong format"); } else putchar(template[pos]); } } int main(void) { int wt; read_template(); while ((wt = more_mail())) process_mail(wt); return 0; }
A feladat kiírása; megoldás letöltése: z2f2.c.
#include <stdio.h> #include <stdlib.h> #define MAX_TRAIN 50 void printtime(int t) { printf("%02d:%02d", t/60, t%60); } int scantime() { int hour, min; if (2 != scanf("%d:%d", &hour, &min)) exit(1); return 60 * hour + min; } int train0_depart[MAX_TRAIN], train0_arrive[MAX_TRAIN]; int train1_depart[MAX_TRAIN], train1_arrive[MAX_TRAIN]; int main(void) { int ntrains0, ntrains1, k; int leave_time, first_walk, board0_time, board1_time, latest_unboard0_time, latest_unboard1_time, second_walk, latest_arrive_time; if (1 != scanf("%d", &first_walk)) exit(1); latest_arrive_time = scantime(); if (1 != scanf("%d", &second_walk)) exit(1); latest_unboard1_time = latest_arrive_time - second_walk; if (1 != scanf("%d", &ntrains0)) exit(1); for (k = 0; k < ntrains0; k++) { train0_depart[k] = scantime(); train0_arrive[k] = scantime(); } if (1 != scanf("%d", &ntrains1)) exit(1); for (k = 0; k < ntrains1; k++) { train1_depart[k] = scantime(); train1_arrive[k] = scantime(); } board1_time = -10000; for (k = 0; k < ntrains1; k++) { if (train1_arrive[k] <= latest_unboard1_time) { if (board1_time < train1_depart[k]) { board1_time = train1_depart[k]; } } } latest_unboard0_time = board1_time; board0_time = -10000; for (k = 0; k < ntrains0; k++) { if (train0_arrive[k] <= latest_unboard0_time) { if (board0_time < train0_depart[k]) { board0_time = train0_depart[k]; } } } leave_time = board0_time - first_walk; printtime(leave_time); printf("\n"); return 0; }
A feladat kiírása; megoldás letöltése: z2f3.c.
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int max(int x, int y) { return x < y ? y : x; } #define PLANBUF_LEN 512 #define PREC_ATOM 0 #define PREC_POWER 2 #define PREC_QUOTIENT 3 #define PREC_PRODUCT 4 #define PREC_SUM 5 struct plan { int width; int height; int depth; int prec; int head; const struct plan *lhs; const struct plan *rhs; } planbuf[PLANBUF_LEN]; int plancnt; void init(void) { plancnt = 0; } struct plan * allocplan(void) { struct plan *r; r = planbuf + plancnt++; if (PLANBUF_LEN < plancnt) exit(1); r->lhs = r->rhs = 0; r->prec = r->head = -1; r->width = r->height = r->depth = 32767; return r; } const struct plan * parenthisize(const struct plan *l) { struct plan *p; p = allocplan(); p->head = '('; p->lhs = l; p->width = l->width + 2; p->height = l->height; p->depth = l->depth; p->prec = PREC_ATOM; return p; } const struct plan * layout(const char **formulap) { struct plan *p; char head; const struct plan *l, *r; p = allocplan(); p->head = head = *(*formulap)++; if (isdigit(head) || islower(head)) { p->width = 1; p->height = 1; p->depth = 0; p->prec = PREC_ATOM; } else { l = layout(formulap); r = layout(formulap); if ('^' == head) { if (PREC_POWER <= l->prec) l = parenthisize(l); p->width = l->width + r->width; p->height = max(l->height, 1 + r->depth + r->height); p->depth = l->depth; p->prec = PREC_POWER; } else if ('/' == head) { p->width = 2 + max(l->width, r->width); p->height = 1 + l->height + l->depth; p->depth = r->height + r->depth; p->prec = PREC_QUOTIENT; } else if ('*' == head) { if (PREC_PRODUCT < l->prec) l = parenthisize(l); if (PREC_PRODUCT <= r->prec) r = parenthisize(r); p->width = 1 + l->width + r->width; p->height = max(l->height, r->height); p->depth = max(l->depth, r->depth); p->prec = PREC_PRODUCT; } else if ('+' == head || '-' == head) { if (PREC_SUM <= r->prec) r = parenthisize(r); p->width = 3 + l->width + r->width; p->height = max(l->height, r->height); p->depth = max(l->depth, r->depth); p->prec = PREC_SUM; } else exit(1); p->lhs = l; p->rhs = r; } return p; } #define PAPER_WIDTH 500 #define PAPER_HEIGHT 100 char paper[PAPER_HEIGHT][PAPER_WIDTH]; int box_height, box_width; void erase(const struct plan *p) { int r, c; box_height = p->height + p->depth; box_width = p->width; if (PAPER_HEIGHT < box_height || PAPER_WIDTH < box_width) exit(1); for (r = 0; r < box_height; r++) for (c = 0; c < box_width; c++) paper[r][c] = ' '; } void output(void) { int r, w, c; for (r = 0; r < box_height; r++) { w = box_width; while (' ' == paper[r][w - 1]) w--; for (c = 0; c < w; c++) putchar(paper[r][c]); putchar('\n'); } putchar('\n'); } void paint(const struct plan *p, int row, int col) { int r, c; int head; if ( row - p->height + 1 < 0 || box_height < row + p->depth || col < 0 || box_width < col + p->width ) exit(1); head = p->head; switch (head) { case '(': for (r = row - p->height + 1; r <= row + p->depth; r++) { paper[r][col] = '('; paper[r][col + p->width - 1] = ')'; } paint(p->lhs, row, 1 + col); break; case '^': paint(p->lhs, row, col); paint(p->rhs, row - max(p->lhs->height - p->rhs->height, 1 + p->rhs->depth), col + p->lhs->width); break; case '/': for (c = col; c < col + p->width; c++) paper[row][c] = '-'; paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2); paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2); break; case '*': paint(p->lhs, row, col); paint(p->rhs, row, 1 + col + p->lhs->width); break; case '+': case '-': paint(p->lhs, row, col); paper[row][1 + col + p->lhs->width] = head; paint(p->rhs, row, 3 + col + p->lhs->width); break; default: if (isdigit(head) || islower(head)) paper[row][col] = head; else exit(1); break; } } void paint_main(const struct plan *p) { paint(p, p->height - 1, 0); } #define FORMULA_LEN 512 int main(void) { char formulabuf[FORMULA_LEN]; const struct plan *p; const char *formula; while (fgets(formulabuf, FORMULA_LEN, stdin)) { formula = formulabuf; init(); p = layout(&formula); if ('\n' != *formula) exit(1); erase(p); paint_main(p); output(); } return 0; }