Starry Night [USACO]

这道题目也比较简单,先想好怎么写,稍微写写伪代码,之后实现了即可。

 

/*
ID: zhangyc1
LANG: C++
TASK: starry
*/
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;

struct SStar 
{
    int nStarNum, nLeft, nRight, nTop, nBottom;
    bool arrIsStar[100][100];
    SStar():nStarNum(1), nLeft(0), nTop(0), nRight(100), nBottom(100){memset(arrIsStar, 0, sizeof(arrIsStar));}
};
SStar arrStar[27];
bool arrVisited[100][100];
char arrChMap[100][101], arrSkyMap[100][101];
int H, W;
int nCurStarIdx = 0;
int arrDirectionY[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int arrDirectionX[8] = {-1, -1, 0, 1, 1, 1, 0, -1};// 上-右上-右-右下-下-左下-左-左上
void GenStar(int x, int y);

void prepairData()
{
    scanf("%d%d", &W, &H);
    for (int i = 0; i < H; i++)
    {
        scanf("%s", arrSkyMap[i]);
        memset(arrChMap[i], '0', W);
        arrChMap[i][W] = '\0';
    }
}

void process()
{
    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            if (!arrVisited[i][j] && arrSkyMap[i][j] == '1')
            {
                GenStar(i, j);
            }
        }
    }

    for (int i = 0; i < H; i++)
    {
        printf("%s\n", arrChMap[i]);
    }
}

int main(){
    freopen("starry.in","r",stdin);
    freopen("starry.out","w",stdout);
    prepairData();
    process();
    return 0;
}

void dfs(int x, int y)
{
    //printf("X = %d,Y = %d\n", x, y);
    arrStar[nCurStarIdx].nStarNum++;
    arrStar[nCurStarIdx].arrIsStar[x][y] = true;
    arrVisited[x][y] = true;
    if (x < arrStar[nCurStarIdx].nTop)
        arrStar[nCurStarIdx].nTop = x;
    if (y < arrStar[nCurStarIdx].nLeft)
        arrStar[nCurStarIdx].nLeft = y;
    if (y > arrStar[nCurStarIdx].nRight)
        arrStar[nCurStarIdx].nRight = y;
    if (x > arrStar[nCurStarIdx].nBottom)
        arrStar[nCurStarIdx].nBottom = x;
    // 判断8个方向
    for (int i = 0; i < 8; i++)
    {
        int newX = x + arrDirectionX[i], newY = y + arrDirectionY[i];
        if (newX >= 0 && newX < H && newY >= 0 && newY < W && !arrVisited[newX][newY] && arrSkyMap[newX][newY] == '1')
            dfs(newX, newY);
    }
}

bool CompareStar(int nStar1, int nStar2)
{
    if (arrStar[nStar1].nStarNum != arrStar[nStar2].nStarNum)
        return false;
    
    if (arrStar[nStar1].nRight - arrStar[nStar1].nLeft == arrStar[nStar2].nBottom - arrStar[nStar2].nTop
        && arrStar[nStar1].nBottom - arrStar[nStar1].nTop == arrStar[nStar2].nRight - arrStar[nStar2].nLeft)
    {
        bool bEqual = true;
        // 右旋90
        for (int i = arrStar[nStar1].nLeft; i <= arrStar[nStar1].nRight && bEqual; i++)
        {// 每列变为行
            int nLineRe = i - arrStar[nStar1].nLeft + arrStar[nStar2].nTop;
            for (int j = arrStar[nStar1].nBottom; j >= arrStar[nStar1].nTop; j--)
            {
                int nColRe = arrStar[nStar1].nBottom - j + arrStar[nStar2].nLeft;
                if (arrStar[nStar1].arrIsStar[j][i] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
        bEqual = true;

        // 右旋270
        for (int i = arrStar[nStar1].nRight; i >= arrStar[nStar1].nLeft && bEqual; i--)
        {// 每列变为行
            int nLineRe = arrStar[nStar1].nRight - i + arrStar[nStar2].nTop;
            for (int j = arrStar[nStar1].nTop; j <= arrStar[nStar1].nBottom; j++)
            {
                int nColRe = j - arrStar[nStar1].nTop + arrStar[nStar2].nLeft;
                if (arrStar[nStar1].arrIsStar[j][i] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
        bEqual = true;

        // 右旋90 并左右互换
        for (int i = arrStar[nStar1].nLeft; i <= arrStar[nStar1].nRight && bEqual; i++)
        {// 每列变为行
            int nLineRe = i - arrStar[nStar1].nLeft + arrStar[nStar2].nTop;
            for (int j = arrStar[nStar1].nBottom; j >= arrStar[nStar1].nTop; j--)
            {
                int nColRe = arrStar[nStar2].nRight - arrStar[nStar1].nBottom + j;
                if (arrStar[nStar1].arrIsStar[j][i] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
        bEqual = true;

        // 右旋270 并左右互换
        for (int i = arrStar[nStar1].nRight; i >= arrStar[nStar1].nLeft && bEqual; i--)
        {// 每列变为行
            int nLineRe = arrStar[nStar1].nRight - i + arrStar[nStar2].nTop;
            for (int j = arrStar[nStar1].nTop; j <= arrStar[nStar1].nBottom; j++)
            {
                int nColRe = arrStar[nStar2].nRight - j + arrStar[nStar1].nTop;
                if (arrStar[nStar1].arrIsStar[j][i] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
    }

    if (arrStar[nStar1].nRight - arrStar[nStar1].nLeft == arrStar[nStar2].nRight - arrStar[nStar2].nLeft
        && arrStar[nStar1].nBottom - arrStar[nStar1].nTop == arrStar[nStar2].nBottom - arrStar[nStar2].nTop)
    {
        bool bEqual = true;
        // 原状
        for (int i = arrStar[nStar1].nTop; i <= arrStar[nStar1].nBottom && bEqual; i++)
        {
            int nLineRe = i - arrStar[nStar1].nTop + arrStar[nStar2].nTop;
            for (int j = arrStar[nStar1].nLeft; j <= arrStar[nStar1].nRight; j++)
            {
                int nColRe = j - arrStar[nStar1].nLeft + arrStar[nStar2].nLeft;
                if (arrStar[nStar1].arrIsStar[i][j] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
        bEqual = true;

        // 左右互换
        for (int i = arrStar[nStar1].nTop; i <= arrStar[nStar1].nBottom && bEqual; i++)
        {
            int nLineRe = i - arrStar[nStar1].nTop + arrStar[nStar2].nTop;
            for (int j = arrStar[nStar1].nLeft; j <= arrStar[nStar1].nRight; j++)
            {
                int nColRe = arrStar[nStar2].nRight - j + arrStar[nStar1].nLeft;
                if (arrStar[nStar1].arrIsStar[i][j] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
        bEqual = true;

        // 上下互换
        for (int i = arrStar[nStar1].nTop; i <= arrStar[nStar1].nBottom && bEqual; i++)
        {
            int nLineRe = arrStar[nStar2].nBottom - i + arrStar[nStar1].nTop;
            for (int j = arrStar[nStar1].nLeft; j <= arrStar[nStar1].nRight; j++)
            {
                int nColRe = j - arrStar[nStar1].nLeft + arrStar[nStar2].nLeft;
                if (arrStar[nStar1].arrIsStar[i][j] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
        bEqual = true;

        // 上下+左右互换
        for (int i = arrStar[nStar1].nTop; i <= arrStar[nStar1].nBottom && bEqual; i++)
        {
            int nLineRe = arrStar[nStar2].nBottom - i + arrStar[nStar1].nTop;
            for (int j = arrStar[nStar1].nLeft; j <= arrStar[nStar1].nRight; j++)
            {
                int nColRe = arrStar[nStar2].nRight - j + arrStar[nStar1].nLeft;
                if (arrStar[nStar1].arrIsStar[i][j] != arrStar[nStar2].arrIsStar[nLineRe][nColRe])
                {
                    bEqual = false;
                    break;
                }
            }
        }
        if (bEqual)
            return true;
    }

    return false;   
}

int FindSimilar()
{
    for (int i = 0; i < nCurStarIdx; i++)
    {
        bool bSimilar = CompareStar(i, nCurStarIdx);
        if (bSimilar)
            return i;
    }
    return -1;
}

void MarkStar(int i, char ch)
{
    for (int m = arrStar[i].nTop; m <= arrStar[i].nBottom; m++)
    {
        for (int n = arrStar[i].nLeft; n <= arrStar[i].nRight; n++)
        {
            if (arrStar[i].arrIsStar[m][n])
                arrChMap[m][n] = ch;
        }
    }
}

void GenStar(int x, int y)
{
    arrStar[nCurStarIdx].nLeft = arrStar[nCurStarIdx].nTop = 100, arrStar[nCurStarIdx].nRight = arrStar[nCurStarIdx].nBottom = arrStar[nCurStarIdx].nStarNum = 0;
    memset(arrStar[nCurStarIdx].arrIsStar, 0, sizeof(arrStar[nCurStarIdx].arrIsStar));
    dfs(x, y);
    // 从0 -- nCurStarIdx 查找此星图,如未找到则记录此次星图
    int nFindRs = FindSimilar();
    if (nFindRs >= 0)
    {
        MarkStar(nCurStarIdx, 'a' + nFindRs);
    }
    else
    {
        MarkStar(nCurStarIdx, 'a' + nCurStarIdx);
        nCurStarIdx++;
    }
}

 

转载于:https://www.cnblogs.com/doublemystery/archive/2013/04/19/3030415.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值