UVa201 - Squares

題目

輸入

分為三部分。
第一部分占一行,含一個(gè)整數(shù) n,代表 n*n 個(gè)點(diǎn)構(gòu)成的 n階 正方形。
第二部分占一行,含一個(gè)整數(shù) m,代表下面將輸入 m 行指令進(jìn)行連線。
第三部分占 m 行,每行含一個(gè)字符和兩數(shù)字,形如:

C i j

H i j 表示點(diǎn)(i,j)與點(diǎn)(i,j + 1)連線;
V i j 表示點(diǎn)(j,i)與點(diǎn)(j + 1,i)(這里要特別留意)連線;

處理

要求求出在該圖中有多少個(gè)正方形,且區(qū)分大?。╯ize 1~9)。

例子輸入輸出

分析

由于要儲(chǔ)存圖的這種特殊形式,所以想到用結(jié)構(gòu)體:含有四個(gè)指針0,1,2,3分別指向上方,右方,下方和左方。然后為了方便遍歷,所以用結(jié)構(gòu)體二維數(shù)組來(lái)儲(chǔ)存所有的點(diǎn)。
連線的時(shí)候就用指針指向?qū)?yīng)要連接的位置,沒(méi)有線的方向就用NULL。

遍歷要分兩大層:
第一大層是遍歷所有的可能滿足的起始點(diǎn),這里用函數(shù)“包裝”,n 代表要查找的n階正方形(一條邊n個(gè)點(diǎn));max 代表該圖的實(shí)際大小,防止遍歷出界。不難發(fā)現(xiàn),我們并不需要遍歷圖上所有點(diǎn)。因?yàn)槿绻鹗键c(diǎn)充當(dāng)小正方形的左上角,那起始點(diǎn)最多到max - n就可以了,再往后就會(huì)出界。
第二大層是遍歷從起始點(diǎn)出發(fā)的n階正方形(其實(shí)最多只有一個(gè)正方形)。用一個(gè)循環(huán)變量作方向(1,2,3,0順時(shí)針),另一個(gè)變量作邊長(zhǎng) n 個(gè)點(diǎn)(不是線)。如此循環(huán)如果是正方形必會(huì)返回到原點(diǎn)。但也要小心一動(dòng)不動(dòng)的也是在呆在原點(diǎn),所以還要判斷這個(gè)點(diǎn)是否與右邊連線。
由此一來(lái)基本完成。

代碼

#define maxn 11
#include <stdio.h>
#include <string.h>

struct point{
    //0 ~ 3 代表從 向上 開(kāi)始順時(shí)針的四個(gè)方向
    struct point * con[4];
    point() { con[0] = con[1] = con[2] = con[3] = NULL;     }
    void clear() { con[0] = con[1] = con[2] = con[3] = NULL; }
} po[maxn][maxn];

void H(int r, int c) {
    po[r][c].con[1] = &po[r][c + 1];
    po[r][c+1].con[3] = &po[r][c];
}

void V(int c, int r) {
    po[r][c].con[2] = &po[r+1][c];
    po[r+1][c].con[0] = &po[r][c];
}

int check(int n, int max) {
    int num = 0;
    //遍歷所有要遍歷的點(diǎn)
    for (int i = 1; i <= max - n + 1; i++) for (int j = 1; j <= max - n + 1; j++) {
        struct point * p = &po[i][j];
        int flag = 1;
        //遍歷一個(gè)點(diǎn)是否連成一個(gè)完整的 n 階正方形,d 控制遍歷方向,k 控制邊長(zhǎng)
        for (int d = 1; flag; d = (d+1) % 4) for (int k = 1; k < n; k++) {
            if (p->con[d] == NULL) { flag = 0; break; }
            p = p->con[d];
            //d 為 0 既往上的時(shí)候退出方向的遍歷
            flag = d;
        }
        if (p == &po[i][j] && p->con[1] != NULL) ++num;
    }
    return num;
}

int main() {
#ifdef TEST
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif // TEST

    int n, m, kase=0;
    while (scanf("%d", &n) != EOF && n) {
        scanf("%d", &m);
        //初始化點(diǎn)之間的連線
        for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) po[i][j].clear();
        //連線
        while (m--) {
            char cmd[5]; int i, j;
            scanf("%s%d%d", cmd, &i, &j);
            if (cmd[0] == 'H') H(i, j);
            else V(i, j);
        }
        //輸出
        if (kase++) printf("\n**********************************\n\n");
        printf("Problem #%d\n\n", kase);
        int ans[maxn], num, flag=0; 
        memset(ans, 0, sizeof(ans));
        for (int i = 2; i <= n; i++)
            if (num = check(i, n))   //i是點(diǎn)數(shù),所以要 -1換算為邊數(shù)
                printf("%d square (s) of size %d\n", num, i-1), flag =1;
        if (!flag)printf("No completed squares can be found.\n");
    }
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • sì 支zhī茶chá 對(duì)duì 酒jiǔ,賦fù 對(duì)duì 詩(shī)shī,燕yàn子zi 對(duì)duì 鶯yīng 兒é...
    每個(gè)人的孟母堂閱讀 1,452評(píng)論 0 6
  • 一年級(jí)語(yǔ)文上冊(cè)生字表 生字表一(共400字) 啊(ā)愛(ài)(ài)安(ān)岸(àn)爸(bà)八(bā)巴(bā)...
    meychang閱讀 3,156評(píng)論 0 6
  • 在C語(yǔ)言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來(lái)閱讀 4,061評(píng)論 0 2
  • 日子山高水長(zhǎng)。 我吾將以夢(mèng)為馬,詩(shī)酒趁年華。 跨過(guò)山和大海,也翻過(guò)人山人海。 第一記 魚(yú)的靈魂 前天,覺(jué)得自己是...
    夏木yi閱讀 424評(píng)論 0 4
  • 月光凌亂的光線 斜斜地跌落在我的書(shū)脊上 依舊如昔 安靜地坐在臺(tái)燈下 翻閱著我愛(ài)的文字 逐行逐字 入眼入心 今夜 唯...
    慕容文兮閱讀 212評(píng)論 0 1

友情鏈接更多精彩內(nèi)容