#include <string.h>#include <iostream>#include <vector>#include <stdio.h>using namespace std;#define MAX_DIM 250#define INIT_COLOR 'O'typedef int Dim_t;typedef char Color_t;struct Graph{ Graph() : Row(0), Col(0) { } Color_t Pixel[MAX_DIM][MAX_DIM]; Dim_t Row; Dim_t Col;};class DrawOP{public: virtual ~DrawOP() {} virtual void Execute(Graph& graph) = 0;};class Init : public DrawOP{public: Init(Dim_t row, Dim_t col) : Row(row), Col(col) {} void Execute(Graph& graph) { for(Dim_t i = 0; i < Row; ++i) { memset(graph.Pixel[i], INIT_COLOR, Col * sizeof(graph.Pixel[0][0])); } graph.Row = Row; graph.Col = Col; }private: Dim_t Row, Col;};class Clear : public DrawOP{public: void Execute(Graph& graph) { for(Dim_t i = 0; i < graph.Row; ++i) { memset(graph.Pixel[i], INIT_COLOR, graph.Col * sizeof(graph.Pixel[0][0])); } }};class LPixel : public DrawOP{public: LPixel(Dim_t row, Dim_t col, Color_t color) : Row(row), Col(col), Color(color) {} void Execute(Graph& graph) { graph.Pixel[Row][Col] = Color; }private: Dim_t Row, Col; Color_t Color;};#define MAX(x, y) ((x) > (y) ? (x) : (y))#define MIN(x, y) ((x) > (y) ? (y) : (x))class VLINE : public DrawOP{public: VLINE(Dim_t col, Dim_t startRow, Dim_t endRow, Color_t color) : Col(col), StartRow(MIN(startRow, endRow)), EndRow(MAX(startRow, endRow)), Color(color) {} void Execute(Graph& graph) { for(Dim_t i = StartRow; i <= EndRow; ++i) { graph.Pixel[i][Col] = Color; } }private: Dim_t Col, StartRow, EndRow; Color_t Color;};class HLINE : public DrawOP{public: HLINE(Dim_t row, Dim_t startCol, Dim_t endCol, Color_t color) : Row(row), StartCol(MIN(startCol, endCol)), EndCol(MAX(startCol, endCol)), Color(color) {} void Execute(Graph& graph) { for(Dim_t i = StartCol; i <= EndCol; ++i) { graph.Pixel[Row][i] = Color; } }private: Dim_t Row, StartCol, EndCol; Color_t Color;};class KRec : public DrawOP{public: KRec(Dim_t topLeftX, Dim_t topLeftY, Dim_t bottomRightX, Dim_t bottomRightY, Color_t color) : TopLeftX(MIN(topLeftX, bottomRightX)), TopLeftY(MIN(topLeftY, bottomRightY)), BottomRightX(MAX(topLeftX, bottomRightX)), BottomRightY(MAX(topLeftY, bottomRightY)), Color(color) {} void Execute(Graph& graph) { for(Dim_t i = TopLeftY; i <= BottomRightY; ++i) { for(Dim_t j = TopLeftX; j <= BottomRightX; ++j) { graph.Pixel[i][j] = Color; } } }private: Dim_t TopLeftX, TopLeftY, BottomRightX, BottomRightY; Color_t Color;};class Fill : public DrawOP{public: Fill(Dim_t row, Dim_t col, Color_t color) : Row(row), Col(col), Color(color) {} void Execute(Graph& graph) { DoFill(graph, Row, Col, Color); }private: void DoFill(Graph& graph, Dim_t row, Dim_t col, Color_t newColor) { Color_t oldColor = graph.Pixel[row][col]; if (oldColor == newColor) return; graph.Pixel[row][col] = newColor; if ((row > 0) && (graph.Pixel[row - 1][col] == oldColor)) // upper DoFill(graph, row - 1, col, newColor); if ((col > 0) && (graph.Pixel[row][col - 1] == oldColor)) // left DoFill(graph, row, col - 1, newColor); if ((row < (graph.Row - 1)) && (graph.Pixel[row + 1][col] == oldColor)) // below DoFill(graph, row + 1, col, newColor); if ((col < (graph.Col - 1)) && (graph.Pixel[row][col + 1] == oldColor)) // right DoFill(graph, row, col + 1, newColor); }private: Dim_t Row, Col; Color_t Color;};class SOutput : public DrawOP{public: SOutput(char* fileName) { int len = strlen(fileName) + 1; FileName = new char[len]; memcpy(FileName, fileName, len * sizeof(char)); } ~SOutput() { delete FileName; } void Execute(Graph& graph) { cout << FileName << endl; for(Dim_t i = 0; i < graph.Row; ++i) { for(Dim_t j = 0; j < graph.Col; ++j) { cout << graph.Pixel[i][j]; } cout << endl; } }private: char* FileName;};void ExecuteCmds(vector<DrawOP*>& ops, Graph& graph){ for(size_t i = 0; i < ops.size(); ++i) ops[i]->Execute(graph);}void ClearCmds(vector<DrawOP*>& ops){ for(size_t i = 0; i < ops.size(); ++i) delete ops[i]; ops.clear();}#define BUF_SIZE 1024bool ParseCmd_Char(vector<DrawOP*>& ops, char cmd, Graph& graph){ Dim_t u, v, w, x; Color_t color; static char tmp[BUF_SIZE]; switch(cmd) { case 'I': cin >> u >> v; ops.push_back(new Init(v, u)); break; case 'C': ops.push_back(new Clear()); break; case 'L': cin >> u >> v >> color; ops.push_back(new LPixel(v-1, u-1, color)); break; case 'V': cin >> u >> v >> w >> color; ops.push_back(new VLINE(u-1, v-1, w-1, color)); break; case 'H': cin >> u >> v >> w >> color; ops.push_back(new HLINE(w-1, u-1, v-1, color)); break; case 'K': cin >> u >> v >> w >> x >> color; ops.push_back(new KRec(u-1, v-1, w-1, x-1, color)); break; case 'F': cin >> u >> v >> color; ops.push_back(new Fill(v-1, u-1, color)); break; case 'S': cin >> tmp; ops.push_back(new SOutput(tmp)); ExecuteCmds(ops, graph); ClearCmds(ops); break; case 'X': return false; default: cin >> tmp; } return true;}char* StepToFirstNonSpace(char* line){ char* pTmp = line; while((*pTmp) == ' ') ++pTmp; return pTmp;}void GetInfos(Dim_t& a, Dim_t& b, char* line){ char* pValidLine = StepToFirstNonSpace(line); sscanf(pValidLine, "%d %d", &a, &b);}void GetInfos(Dim_t& a, Dim_t& b, Color_t& color, char* line){ char* pValidLine = StepToFirstNonSpace(line); sscanf(pValidLine, "%d %d %c", &a, &b, &color);}void GetInfos(Dim_t& a, Dim_t& b, Dim_t& c, Color_t& color, char* line){ char* pValidLine = StepToFirstNonSpace(line); sscanf(pValidLine, "%d %d %d %c", &a, &b, &c, &color);}void GetInfos(Dim_t& a, Dim_t& b, Dim_t& c, Dim_t& d, Color_t& color, char* line){ char* pValidLine = StepToFirstNonSpace(line); sscanf(pValidLine, "%d %d %d %d %c", &a, &b, &c, &d, &color);}void GetInfos(char* dest, char* line){ char* pValidLine = StepToFirstNonSpace(line); sscanf(pValidLine, "%s", dest);}bool ParseCmd_Str(vector<DrawOP*>& ops, char* cmd, Graph& graph){ Dim_t u, v, w, x; Color_t color; static char fileName[BUF_SIZE]; switch(cmd[0]) { case 'I': GetInfos(u, v, cmd + 1); ops.push_back(new Init(v, u)); break; case 'C': ops.push_back(new Clear()); break; case 'L': GetInfos(u, v, color, cmd + 1); ops.push_back(new LPixel(v-1, u-1, color)); break; case 'V': GetInfos(u, v, w, color, cmd + 1); ops.push_back(new VLINE(u-1, v-1, w-1, color)); break; case 'H': GetInfos(u, v, w, color, cmd + 1); ops.push_back(new HLINE(w-1, u-1, v-1, color)); break; case 'K': GetInfos(u, v, w, x, color, cmd + 1); ops.push_back(new KRec(u-1, v-1, w-1, x-1, color)); break; case 'F': GetInfos(u, v, color, cmd + 1); ops.push_back(new Fill(v-1, u-1, color)); break; case 'S': GetInfos(fileName, cmd + 1); ops.push_back(new SOutput(fileName)); ExecuteCmds(ops, graph); ClearCmds(ops); break; case 'X': return false; } return true;}void InputCmds(vector<DrawOP*>& ops, Graph& graph){ char cmd[BUF_SIZE]; while(true) { fgets(cmd, BUF_SIZE, stdin); if (!ParseCmd_Str(ops, cmd, graph)) return; }}int main(int argc, char* argv[]){ Graph graph; vector<DrawOP*> ops; InputCmds(ops, graph); ExecuteCmds(ops, graph); ClearCmds(ops); return 0;}