Run Time: 0.013
Ranking (as of 2016-03-02): 1 out of 410
Language: C++
/* UVa 338 - Long Multiplication To build using Visual Studio 2012: cl -EHsc -O2 UVa_338_Long_Multiplication.cpp */ #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int nr_digits_max = 10, nr_chars_max = nr_digits_max * 2; struct line { bool zero_; int start_, end_; char buff_[nr_chars_max + 1]; } x_line, y_line, horizontal_line, lines[nr_digits_max + 1]; void print_line(line& l, int min_start) { memset(l.buff_ + min_start, ' ', l.start_ - min_start); puts(&l.buff_[min_start]); } void print_horizontal_line(int length, int min_start) { horizontal_line.start_ = nr_chars_max - length; horizontal_line.end_ = nr_chars_max; memset(&horizontal_line.buff_[horizontal_line.start_], '-', length); print_line(horizontal_line, min_start); } int main() { long long x, y; while (scanf("%lld %lld", &x, &y) == 2) { int min_start = nr_chars_max; // x x_line.zero_ = !x, x_line.start_ = x_line.end_ = nr_chars_max; do { x_line.buff_[--x_line.start_] = x % 10 + '0'; x /= 10; } while (x); #ifdef DEBUG puts(&x_line.buff_[x_line.start_]); #endif min_start = min(min_start, x_line.start_); // y y_line.zero_ = !y, y_line.start_ = y_line.end_ = nr_chars_max; do { y_line.buff_[--y_line.start_] = y % 10 + '0'; y /= 10; } while (y); #ifdef DEBUG puts(&y_line.buff_[y_line.start_]); #endif min_start = min(min_start, y_line.start_); if (x_line.zero_ || y_line.zero_) { print_line(x_line, min_start); print_line(y_line, min_start); print_horizontal_line(nr_chars_max - min_start, min_start); lines[0].start_ = nr_chars_max - 1, lines[0].end_ = nr_chars_max; lines[0].buff_[nr_chars_max - 1] = '0'; print_line(lines[0], min_start); putchar('\n'); continue; } int nr_lines = 0, nr_shift = 0; for (int i = y_line.end_ - 1; i >= y_line.start_; i--, nr_shift++) { line& l = lines[nr_lines]; l.zero_ = true; l.start_ = l.end_ = nr_chars_max - nr_shift; l.buff_[l.end_] = '\0'; int d = 0, dy = y_line.buff_[i] - '0'; for (int j = x_line.end_ - 1; j >= x_line.start_; j--) { d += dy * (x_line.buff_[j] - '0'); if ((l.buff_[--l.start_] = d % 10 + '0') != '0') l.zero_ = false; d /= 10; } while (d) { if ((l.buff_[--l.start_] = d % 10 + '0') != '0') l.zero_ = false; d /= 10; } if (!l.zero_) { #ifdef DEBUG puts(&l.buff_[l.start_]); #endif nr_lines++; min_start = min(min_start, l.start_); } } if (nr_lines > 1) { line& l = lines[nr_lines]; l.start_ = l.end_ = nr_chars_max; int d = 0; for (int i = nr_chars_max - 1; i >= min_start; i--) { for (int j = 0; j < nr_lines; j++) if (!lines[j].zero_ && i >= lines[j].start_ && i < lines[j].end_) d += lines[j].buff_[i] - '0'; l.buff_[--l.start_] = d % 10 + '0'; d /= 10; } while (d) { l.buff_[--l.start_] = d % 10 + '0'; d /= 10; } #ifdef DEBUG puts(&l.buff_[l.start_]); #endif min_start = min(min_start, l.start_); nr_lines++; } print_line(x_line, min_start); print_line(y_line, min_start); print_horizontal_line( max(x_line.end_ - x_line.start_, y_line.end_ - y_line.start_), min_start); if (nr_lines > 1) { for (int i = 0; i < nr_lines - 1; i++) if (!lines[i].zero_) print_line(lines[i], min_start); print_horizontal_line(nr_chars_max - min_start, min_start); } else { line& l = lines[0]; memset(&l.buff_[l.end_], '0', nr_chars_max - l.end_); } print_line(lines[nr_lines - 1], min_start); putchar('\n'); } return 0; }
No comments:
Post a Comment