習題4-2 正方形
阿新 • • 發佈:2018-11-28
題目:
大意就是給出n和m,構造N^2點數的正方形並輸入m條指令:
H i j 代表橫向連線座標為 (i, j)和座標為 (i, j + 1)的兩點;
V i j 代表縱向連線座標為 (i, j)和座標為 (i + 1, j)的兩點。
問最終能連成不同邊長的正方形各多少個。
解析:
對於不同的指令,我想到用兩個陣列V[n][n]和H[n][n]來保留操作,對於每個點的座標,分別統計以它為起點的不同邊長正方形的個數,最後加和即可。假設最初兩個陣列全為0,聯通則置1,那麼判斷應該為:
if (!H[i][j + k] || !H[i + len][j + k]) { flag = 0;break; } if (!V[i + k][j] || !V[i + k][j + len]) { flag = 0;break; }
可是真到了程式設計卻不能越過邏輯的坎兒。看了一下網上其他人的程式碼,才發現是自己的邏輯出錯了。正確的想法應該是:對於不同邊長的正方形個數進行依次統計(這是最外層迴圈,這樣才能有i+len<=n的限制條件),一個正方形如果完整,那麼它的每條邊都存在,因此在最內層迴圈遍歷它的每條邊,只要有一條邊不存在即可退出,否則計數。
程式碼:
//習題4-2 正方形 #include<iostream> #include<Windows.h> #include<algorithm> #include<cstdio> #include<cstring> #include<ctype.h> #include<cmath> #define MAXN 10 using namespace std; int H[MAXN][MAXN], V[MAXN][MAXN]; int main() { int i, j, k, n, m, x, y, len; int flag = 1; int cnt = 0, sum = 0; char ch; cin >> n >> m; memset(V, 0, sizeof(V)); memset(H, 0, sizeof(H)); while(m--) { getchar(); ch = getchar(); scanf("%d%d", &x, &y); if (ch == 'V') V[x][y] = 1; else H[x][y] = 1; } for (len = 1;len <= n;len++) //正方形的邊長範圍 { cnt = 0; for (i = 1;i + len <= n;i++) { for (j = 1;j + len <= n;j++) { flag = 1; for (k = 0;k < len;k++) //遍歷每條邊(個點),只要有不連通的就退出 { if (!H[i][j + k] || !H[i + len][j + k]) { //上與下、左與右座標之間差的是一個邊長 flag = 0;break; } if (!V[i + k][j] || !V[i + k][j + len]) { flag = 0;break; } } cnt += flag; //對於每種邊長的個數 } } sum += cnt; //總個數 if (cnt) printf("%d square (s) of size %d\n", cnt, len); } system("pause"); return 0; }