The Same Game UVA 758/Uvalive 5423 大模拟 求最大联通块并清除

来源:互联网 发布:淘宝与天猫有什么区别 编辑:程序博客网 时间:2024/06/08 11:56

题目:https://cn.vjudge.net/problem/UVA-758

题意:模拟一个游戏,棋盘大小10行15列,取左下角为原点建立坐标系,有三种棋子,题目给出一个初始状态。游戏初始得分为0。
要求进行以下三个阶段的操作:
(1)找到最大联通块,(若有多个优先选择最左的,若还有多个优先选择最下的),若联通块中棋子数>=2则清除,此时会得到(删除的棋子数 - 2)的平方的分数,依照要求输出。否则结束游戏。
(2)所有棋子垂直下落(如果下方有空格子)
(3)若有一整列空出来了,右方各列整体左移。

最终得分:若所有的棋子都被清空,则有1000分的奖励分。
最后输出最终得分和剩余棋子数。

思路:标准的搜索式大模拟,务必把各个功能模块分的足够清楚否则最后调试会疯的。
我是封装了两层结构体,把整个过程分成了,搜索并标记联通块、清除连通块、下落、左移四个部分。标记和清除用dfs完成的。

代码

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>#include <string>#include <stack>#include <queue>#include <vector>#include <map>using namespace std;const int maxn = 20;int movex[] = { 0, 1, 0, -1 };int movey[] = { 1, 0, -1, 0 };struct Node{    char c;    int num;    bool vis;    Node(char cc = 0) : c(cc), num(0), vis(false) {}    void clear()    {        *this = Node();    }    bool isblank()    {        return c == 0;    }};struct Board{    Node node[maxn][maxn];    int index;    map<int, int> cntmap;    int score;    int amount;    int step;    Board()    {        init();    }    void init()    {        amount = 10 * 15;        index = 1;        step = 1;        cntmap.clear();        score = 0;        for (int i = 0; i < maxn; i++)        {            for (int j = 0; j < maxn; j++)            {                node[i][j].clear();            }        }    }    void clearboradvis()    {        for (int i = 1; i <= 10; i++)        {            for (int j = 1; j <= 15; j++)            {                node[i][j].vis = false;            }        }    }    void input()    {        char s[maxn] = { 0 };        for (int i = 1; i <= 10; i++)        {            scanf("%s", s + 1);            for (int j = 1; j <= 15; j++)            {                node[i][j] = Node(s[j]);            }        }    }    int mark()    {        int maxx = 0;        for (int i = 1; i <= 10; i++)        {            for (int j = 1; j <= 15; j++)            {                if (!node[i][j].isblank() && !node[i][j].vis)                {                    dfs(i, j, index, node[i][j].c);                    maxx = max(maxx, cntmap[index++]);                }            }        }        return maxx;    }    bool check(int x, int y)    {        return x >= 1 && x <= 10 && y >= 1 && y <= 15;    }    void dfs(int x, int y, int num, char c)    {        node[x][y].num = num;        node[x][y].vis = true;        cntmap[num]++;        for (int i = 0; i < 4; i++)        {            int newx = x + movex[i];            int newy = y + movey[i];            if (check(newx, newy) && !node[newx][newy].vis && node[newx][newy].c == c)            {                dfs(newx, newy, num, c);            }        }    }    void dfs(int x, int y, int num)    {        node[x][y].num = 0;        node[x][y].c = 0;        node[x][y].vis = true;        for (int i = 0; i < 4; i++)        {            int newx = x + movex[i];            int newy = y + movey[i];            if (check(newx, newy) && !node[newx][newy].vis && node[newx][newy].num == num)            {                dfs(newx, newy, num);            }        }    }    void clearmark()    {        for (int i = 1; i <= 10; i++)        {            for (int j = 1; j <= 15; j++)            {                node[i][j].num = 0;                node[i][j].vis = false;            }        }        index = 1;        cntmap.clear();    }    int getscore(int num)    {        return (num - 2) * (num - 2);    }    bool clearmaxcluster()    {        clearmark();        int maxcluster = mark();        if (maxcluster <= 1)        {            return false;        }        for (int j = 1; j <= 15; j++)        {            for (int i = 10; i >= 1; i--)            {                if (cntmap[node[i][j].num] == maxcluster)                {                    printf("Move %d at (%d,%d): removed %d balls of color %c, got %d points.\n", step++, 10 - i + 1, j, cntmap[node[i][j].num], node[i][j].c, getscore(cntmap[node[i][j].num]));                    clearboradvis();                    score += getscore(cntmap[node[i][j].num]);                    amount -= cntmap[node[i][j].num];                    dfs(i, j, node[i][j].num);                    return true;                }            }        }        return false;    }    void drop(int x, int y)    {        for (int i = x; i < 10; i++)        {            if (node[i + 1][y].isblank())            {                swap(node[i][y], node[i + 1][y]);            }            else            {                return;            }        }    }    void boarddrop()    {        for (int i = 10; i >= 1; i--)        {            for (int j = 1; j <= 15; j++)            {                if (!node[i][j].isblank())                {                    drop(i, j);                }            }        }    }    bool isblankcolumn(int j)    {        for (int i = 10; i >= 1; i--)        {            if (!node[i][j].isblank())            {                return false;            }        }        return true;    }    void moveleft(int j)    {        for (int k = j; k >= 2; k--)        {            if (isblankcolumn(k - 1))            {                for (int i = 1; i <= 10; i++)                {                    swap(node[i][k - 1], node[i][k]);                }            }            else            {                return;            }        }    }    void boardmoveleft()    {        for (int j = 1; j <= 15; j++)        {            moveleft(j);        }    }};Board board;int main(){    int T;    cin >> T;    for (int cases = 1; cases <= T; cases++)    {        if (cases != 1)        {            printf("\n");        }        board.init();        board.input();        printf("Game %d:\n\n", cases);        while (board.clearmaxcluster())        {            board.boarddrop();            board.boardmoveleft();        }        if (board.amount == 0)        {            printf("Final score: %d, with 0 balls remaining.\n", board.score + 1000);        }        else        {            printf("Final score: %d, with %d balls remaining.\n", board.score, board.amount);        }    }    return 0;}
原创粉丝点击