ccf真題-201512-3-畫圖AC題解
阿新 • • 發佈:2018-12-29
1.題目:畫圖-題目
2.輸入輸出:
輸入:第一行-寬度、高度、運算元
在每個操作中:① 0 起止座標 ② 1 起始座標 填充字元
輸出:依次執行操作後的畫圖結果
3.題目分析:看起來題目很花,但是隻要把每個部分拆開來卡就好了,輸入輸出以及陣列的初始化成小數點,很簡單。
判斷操作是劃線還是填充,根據每行的第一個數字就OK,也很簡單。
如何劃線和填充呢?劃線無非是橫座標相同則畫豎線,縱座標相同畫橫線。填充就運用遞迴。需要注意的是,畫線時要考慮到如果已經有線了怎麼辦?如何避免一個格子反覆被遞迴呼叫到?
4.AC程式碼:
// ============================================================================ // File Name : ccf真題-201512-3-畫圖AC程式碼.cpp // Author : Sneexy // Create Time : 2017/03/11 14:48:49 // Update Time : 2017/03/11 14:48:49 // CSDN blog address : http://blog.csdn.net/qq_33810513 // ============================================================================ #include #include using namespace std; int line, row; char point[105][105]; void fill(int i, int j, char ch) { if (point[i][j]==ch || point[i][j] == '-' || point[i][j] == '|' || point[i][j] == '+')return; point[i][j] = ch; if (j)fill(i,j-1 ,ch);//左 if (j < line - 1)fill(i,j+1, ch);//右 if (i)fill(i-1, j , ch);//上 if (i < row - 1)fill(i+1, j , ch);//下 return; } int main() { int i, j,k;//臨時變數 int cinNum, flag, posx, posy,posx1,posy1;//cinNum-輸入組數;flag-操作型別:0-劃線,1 - 填充 char ch; cin >> line >> row >> cinNum; for (i = 0; i < row; i++)// 1.將矩陣初始化為小數點 { for (j = 0; j < line; j++)point[i][j] = '.'; } while (cinNum--)// 2.根據輸入資料進行操作 { cin >> flag; if (flag == 1) { cin >> posx >> posy >> ch; fill(row-1-posy, posx, ch);// 2.1迴圈遍歷上下左右,填充 } if (!flag) //2.2 根據兩點座標劃線 { cin >> posx >> posy >> posx1 >> posy1; if (posx == posx1)//豎線 { if (posy > posy1){ k = posy; posy = posy1; posy1 = k; } for (i = posy; i <= posy1; i++) { //通過分析可知最終結果只有 + | 兩種 if (point[row - 1 - i][posx] == '-' || point[row - 1 - i][posx] == '+')point[row - 1 - i][posx] = '+'; else point[row - 1 - i][posx] = '|'; } } else if (posy==posy1)//橫線 { if (posx > posx1){ k = posx; posx = posx1; posx1 = k; } for (i = posx; i <= posx1; i++) { //通過分析可知最終結果只有 + - 兩種 if (point[row - 1 - posy][i] == '|' || point[row - 1 - posy][i] == '+')point[row - 1 - posy][i] = '+'; else point[row - 1 - posy][i] = '-'; } } } } for (i = 0; i < row; i++)// 3.輸出矩陣 { for (j = 0; j < line; j++) cout << point[i][j]; cout << endl; } return 0; }
5.解題記錄:
重點:——輸入的flag會影響後面的賦值,但是flag跟後續的數同一行輸入對結果無影響; ——輸入的資料如果是兩個int,一個char,通過cin>>intA>>intB>>charC;是可以對char 正確賦值的,輸入時直接“1 2 a”就行 ——判斷條件很重要,而且要理清思路,題目中的i、row是從上到下的行, j、line、posx是從左到右的列,posy是從下到上的行。 ———————————————————————————————————————————————————————————————— 用此程式說明了輸入flag和後續的根據flag輸入的資料,由同一行輸入進去是可行的: #include using namespace std; int main() { int a, b, c, d; int t = 100; while (t--) { cin >> a; if (a == 1) { cin >> b >> c; cout << "b,c: " << b << " " << c << endl; } if (a == 2) { cin >> d; cout << "d: " << d << endl; } } return 0; } 1 2 3 b,c: 2 3 2 2 d: 2 1 2 2 b,c: 2 2 樣例: 3 4 2 1 0 0 b 0 1 0 2 0 發現不能進行繼續的輸入程式就執行完了,猜測是由於遞迴未進行完全的緣故,將 if (point[posx][posy] == '-' || point[posx][posy] == '|' || point[posx][posy] == '+')return; 改為 if(point[posx][posy] != '.')return; 否則如果是已經被填充了的仍然會一直進行填充,修改後可以完整輸入了。 —————————————————————————————————————————————————————————————————— 出現問題是,該輸出的區域沒有輸出,為空白,猜測是因為字元不可以通過等於符號賦值, 通過以下程式碼否定此猜測: char arr[5][5]; for (int i = 0; i < 5;i++) { for (int j = 0; j < 5;j++) { arr[i][j] = 'a'; } } arr[3][3] = 'b'; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { cout << arr[i][j] << " "; }cout << endl; } —————————————————————————————————————— 找出原因是:將輸入line、row放在了迴圈操作初始化前面,導致初始化出錯。 後發現輸入是int int char型別“0 0 b”的時候,char資料會被賦值為b而不是空格。 遞迴時用if(point[posx][posy] != '.')return; 會導致已經被賦值過的位置無法在另外一行填充中使用, 故改為:if (point[i][j]==ch || point[i][j] == '-' || point[i][j] == '|' || point[i][j] == '+')return;
——————————————————————————————