2012年华为杯校园编程大赛决赛 类别:软件C/C++语言

2012年华为杯校园编程大赛决赛

类别:软件C/C++语言

 

 

编程题(共1题,100分。请上机编写程序,按题目要求提交文件。测试用例不对考生公开,凡不满足提交要求导致不能运行或用例不通过,不予评分。)

1.       俄罗斯方块之棋盘覆盖

俄罗斯方块是一款风靡全球的益智类游戏。由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。

本试题是在俄罗斯方块几种常见的方块基础上,在指定大小和障碍的棋盘上,用标准的方块形状,完成对棋盘的覆盖。用于覆盖棋盘的方块可以是下文所给出方块的全集,也可以是其中的任意一个子集,且使用的方块数量不限,形状变化不限。

l 棋盘大小:

棋盘大小为21行21列的正方形。按照从上到下,从左到右,从1开始,依次进行编号,直到最右下方的格子标识为441。

l 可选方块:

可选方块为标准的俄罗斯方块形状,包括其标准的旋转变化。基本形状如图所示:

各形状的变化如图所示(字母为方块编号):

a          b

 

c   d

e          f

g

l 障碍说明:

棋盘上仅有一处障碍无法放置方块,障碍可处于棋盘任意位置。障碍为基本形状a及其所有的旋转变化,如图所示:

 

l 输入输出要求:

输入文件名为testin.txt,格式如下所示,各数字用空格隔开,各数字表示棋盘格子编号。

2 3 22 23

该输入表示障碍位于棋盘的左上角。

输出文件名为testout.txt,要求先输出棋盘覆盖结果,再输出未覆盖的格子个数。输出棋盘用21行21列数字/字母表示,其中0表示未覆盖的格子,1表示障碍,字母表示对应方块编号(字母对应关系见“可选方块”一节)。最后输出未覆盖格子个数。这里以6行10列棋盘举例示意输出格式(注意:实际输出应该是21行21列,对应方块形状用对应的字母表示):

0 e 0 0 0 0 f f f f

e e 0 0 0 1 1 g g g

e 0 0 0 1 1 0 0 0 g

a 0 0 0 c 0 d d 0 0

a a 0 0 c 0 d d b 0

0 a 0 0 c c 0 b b b

28

l 要求:

1、 用所提供的方块尽可能覆盖棋盘并输出结果;

2、 在(1)的基础上,棋盘上的空格越少越好。

l 交付件要求

C/C++:需要提交可执行文件和压缩打包的源代码工程

JAVA:需要提交压缩打包的整个编码工程目录

 

#include <fstream>
#include <iostream>
using namespace std;

/*******************************************************************************
* The maximum map width, height and block size
*******************************************************************************/
const int M_W = 21;
const int M_H = 21;
const int M_N = 4;

/*******************************************************************************
* Current map width, height
*******************************************************************************/
int M_CW = M_W;
int M_CH = M_H;

/*******************************************************************************
* Map for game
*******************************************************************************/
const int M_S = M_W > M_H ? M_W : M_H;
char map[M_S][M_S] = {0};

/*******************************************************************************
* Base class
*******************************************************************************/
class Base
{
public:
    Base(){}
    virtual ~Base(){}
    virtual char GetIDC(void) = 0;
    virtual bool FillAt(int x, int y) = 0;
    virtual bool RemoveAt(int x, int y) = 0;
};

/*******************************************************************************
* Block
*******************************************************************************/
template<char idc>
class Block : public Base
{
public:
    /***************************************************************************
    * Initialize
    ***************************************************************************/
    Block()
    {
        for (int i = 0; i < M_N; i++)
        {
            pos[i] = -1;
        }
    }

    virtual ~Block(){}

    /***************************************************************************
    * Get IDC
    ***************************************************************************/
    virtual char GetIDC(void)
    {
        return idc;
    }

    /***************************************************************************
    * Fill at (x, y)
    ***************************************************************************/
    virtual bool FillAt(int x, int y)
    {
        bool bret;
        for (int i = 0; i < 4; i++)
        {
            bret = CheckMap(x, y);
            if (bret)
            {
                SetMap(x, y);
                return true;
            }
            RotateRight();
        }
        return false;
    }

    /***************************************************************************
    * Remove at (x, y)
    ***************************************************************************/
    virtual bool RemoveAt(int x, int y)
    {
        for (int i = 0; i < M_N; i++)
        {
            if (pos[i] >= 0)
            {
                map[pos[i]/M_W][pos[i]%M_W] = '0';
                pos[i] = -1;
            }
        }
        return true;
    }

    /***************************************************************************
    * Check at (x, y)
    ***************************************************************************/
    virtual bool CheckMap(int x, int y)
    {
        int i, j;
        int xbs, ybs;
        int count = 0;
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                if (block[i][j] == 1)
                {
                    if (count == 0)
                    {
                        xbs = i;
                        ybs = j;
                    }
                    count++;
                    int nx = x+i-xbs;
                    int ny = y+j-ybs;
                    if (nx < 0 || nx >= M_H || ny < 0 || ny >= M_W ||
                        map[nx][ny] != '0')
                    {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /***************************************************************************
    * Set at (x, y)
    ***************************************************************************/
    virtual bool SetMap(int x, int y)
    {
        int i, j;
        int xbs, ybs;
        int count = 0;
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                if (block[i][j] == 1)
                {
                    if (count == 0)
                    {
                        xbs = i;
                        ybs = j;
                    }
                    if (map[x+i-xbs][y+j-ybs] != '0')
                    {
                        return false;
                    }
                    pos[count++] = (x+i-xbs) * 21 + (y+j-ybs) + 1;
                    map[x+i-xbs][y+j-ybs] = idc;
                }
            }
        }
        return true;
    }

    /***************************************************************************
    * Show block
    ***************************************************************************/
    static void Show(void)
    {
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << (block[i][j] == 1 ? '*' : ' ') << " ";
            }
            cout << endl;
        }
    }

protected:
    /***************************************************************************
    * Rotate Left
    ***************************************************************************/
    static void RotateLeft(void)
    {
        int i, j;
        char tmp_block[4][4];
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                tmp_block[i][j] = block[j][3-i];
            }
        }
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                block[i][j] = tmp_block[i][j];
            }
        }
    }

    /***************************************************************************
    * Rotate right
    ***************************************************************************/
    static void RotateRight(void)
    {
        int i, j;
        char tmp_block[4][4];
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                tmp_block[i][j] = block[3-j][i];
            }
        }
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                block[i][j] = tmp_block[i][j];
            }
        }
    }

protected:
    /***************************************************************************
    * Position data
    ***************************************************************************/
    int pos[M_N];

    /***************************************************************************
    * Graph for block
    ***************************************************************************/
    static char block[4][4];
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'a'>::block[4][4] = {
    1, 0, 0, 0,
    1, 1, 0, 0,
    0, 1, 0, 0,
    0, 0, 0, 0,
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'b'>::block[4][4] = {
    1, 1, 1, 0,
    0, 1, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'c'>::block[4][4] = {
    1, 1, 1, 0,
    1, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'d'>::block[4][4] = {
    1, 1, 0, 0,
    1, 1, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'e'>::block[4][4] = {
    0, 1, 0, 0,
    1, 1, 0, 0,
    1, 0, 0, 0,
    0, 0, 0, 0,
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'f'>::block[4][4] = {
    1, 0, 0, 0,
    1, 0, 0, 0,
    1, 0, 0, 0,
    1, 0, 0, 0,
};

/*******************************************************************************
* Graph for block
*******************************************************************************/
char Block<'g'>::block[4][4] = {
    0, 1, 0, 0,
    0, 1, 0, 0,
    1, 1, 0, 0,
    0, 0, 0, 0,
};

/*******************************************************************************
* Using global variable map as parameter
*******************************************************************************/
int solve(void)
{
    int i, j;
    int count = 0;
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            if (map[i][j] == '0')
            {
                Block<'a'> a;
                Block<'b'> b;
                Block<'c'> c;
                Block<'d'> d;
                Block<'e'> e;
                Block<'f'> f;
                Block<'g'> g;
                bool bret = false;
                bret = bret || d.FillAt(i, j);
                bret = bret || f.FillAt(i, j);
                bret = bret || c.FillAt(i, j);
                bret = bret || g.FillAt(i, j);
                bret = bret || a.FillAt(i, j);
                bret = bret || e.FillAt(i, j);
                bret = bret || b.FillAt(i, j);
                if (bret)
                {
                    count += 4;
                }
            }
        }
    }

    return count;
}

/*******************************************************************************
* Map rotate
*******************************************************************************/
void map_rotate()
{
    int i, j;
    char tmp_map[M_S][M_S];
    for (i = 0; i < M_S; i++)
    {
        for (j = 0; j < M_S; j++)
        {
            tmp_map[i][j] = map[j][M_S-1-i];
        }
    }
    for (i = 0; i < M_S; i++)
    {
        for (j = 0; j < M_S; j++)
        {
            map[i][j] = tmp_map[i][j];
        }
    }

    M_CH ^= M_CW ^= M_CH;
    M_CW ^= M_CH;
}

/*******************************************************************************
* Check map and solve
*******************************************************************************/
int rotate_map_and_solve(void)
{
    /***************************************************************************
    * Save map
    ***************************************************************************/
    int i, j;
    char orig_map[M_H][M_W];
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            orig_map[i][j] = map[i][j];
        }
    }

    /***************************************************************************
    * Solve map
    ***************************************************************************/
    char solve_map[M_H][M_W];
    int solve_count = solve();
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            solve_map[i][j] = map[i][j];
        }
    }

    /***************************************************************************
    * Rotate and solve map
    ***************************************************************************/
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = orig_map[i][j];
        }
    }
    map_rotate();
    char save_map[M_H][M_W];
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            save_map[i][j] = map[i][j];
        }
    }
    int solve_count_rotate = solve();
    if (solve_count_rotate > solve_count)
    {
        solve_count = solve_count_rotate;
        map_rotate();
        map_rotate();
        map_rotate();
        for (i = 0; i < M_H; i++)
        {
            for (j = 0; j < M_W; j++)
            {
                solve_map[i][j] = map[i][j];
            }
        }
    }

    /***************************************************************************
    * Rotate and solve map
    ***************************************************************************/
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = save_map[i][j];
        }
    }
    map_rotate();
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            save_map[i][j] = map[i][j];
        }
    }
    solve_count_rotate = solve();
    if (solve_count_rotate > solve_count)
    {
        solve_count = solve_count_rotate;
        map_rotate();
        map_rotate();
        for (i = 0; i < M_H; i++)
        {
            for (j = 0; j < M_W; j++)
            {
                solve_map[i][j] = map[i][j];
            }
        }
    }

    /***************************************************************************
    * Rotate and solve map
    ***************************************************************************/
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = save_map[i][j];
        }
    }
    map_rotate();
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            save_map[i][j] = map[i][j];
        }
    }
    solve_count_rotate = solve();
    if (solve_count_rotate > solve_count)
    {
        solve_count = solve_count_rotate;
        map_rotate();
        for (i = 0; i < M_H; i++)
        {
            for (j = 0; j < M_W; j++)
            {
                solve_map[i][j] = map[i][j];
            }
        }
    }

    /***************************************************************************
    * Set solve map
    ***************************************************************************/
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = solve_map[i][j];
        }
    }
    return solve_count;
}

/*******************************************************************************
* Check map and solve
*******************************************************************************/
int check_map_and_solve(void)
{
    /***************************************************************************
    * Save map
    ***************************************************************************/
    int i, j;
    char orig_map[M_H][M_W];
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            orig_map[i][j] = map[i][j];
        }
    }

    /***************************************************************************
    * Solve map
    ***************************************************************************/
    char solve_map[M_H][M_W];
    int solve_count = solve();
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            solve_map[i][j] = map[i][j];
        }
    }

    /***************************************************************************
    * Rotate and solve map
    ***************************************************************************/
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = orig_map[i][j];
        }
    }
    int solve_count_rotate = rotate_map_and_solve();
    if (solve_count_rotate > solve_count)
    {
        solve_count = solve_count_rotate;
        for (i = 0; i < M_H; i++)
        {
            for (j = 0; j < M_W; j++)
            {
                solve_map[i][j] = map[i][j];
            }
        }
    }

    /***************************************************************************
    * Rotate and solve map
    ***************************************************************************/
    int xf = -1;
    int yf = -1;
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = orig_map[i][j];
            if (map[i][j] == '1' && xf < 0)
            {
                xf = i;
                yf = j;
            }
        }
    }

    /***************************************************************************
    * Find '1' and check if we can add some block
    ***************************************************************************/
    if (xf >= 0)
    {
        /***********************************************************************
        * Check : 
        * 1           1 1
        * 1 1  or   1 1
        *   1
        ***********************************************************************/
        int solve_count_match = 0;
        if (map[xf][yf+1] == '1')
        {
            /*******************************************************************
            * Add c c c
            *     c
            *******************************************************************/
            if (xf >= 1)
            {
                map[xf-1][yf-1] = 'c';
                map[xf-1][yf] = 'c';
                map[xf-1][yf+1] = 'c';
                map[xf][yf-1] = 'c';
                solve_count_match += 4;
            }
            /*******************************************************************
            * Add     c
            *     c c c
            *******************************************************************/
            if (xf < M_H - 2)
            {
                map[xf+1][yf+1] = 'c';
                map[xf+2][yf-1] = 'c';
                map[xf+2][yf] = 'c';
                map[xf+2][yf+1] = 'c';
                solve_count_match += 4;
            }
            solve_count_match += rotate_map_and_solve();
            if (solve_count_match > solve_count)
            {
                solve_count = solve_count_match;
                for (i = 0; i < M_H; i++)
                {
                    for (j = 0; j < M_W; j++)
                    {
                        solve_map[i][j] = map[i][j];
                    }
                }
            }
        }
        else
        {
            /*******************************************************************
            * Add c
            *     c
            *     c c
            *******************************************************************/
            if (yf > 0)
            {
                map[xf][yf-1] = 'c';
                map[xf+1][yf-1] = 'c';
                map[xf+2][yf-1] = 'c';
                map[xf+2][yf] = 'c';
                solve_count_match += 4;
            }
            /*******************************************************************
            * Add c c
            *       c
            *       c
            *******************************************************************/
            if (yf < M_W - 2)
            {
                map[xf][yf+1] = 'c';
                map[xf][yf+2] = 'c';
                map[xf+1][yf+2] = 'c';
                map[xf+2][yf+2] = 'c';
                solve_count_match += 4;
            }
            solve_count_match += rotate_map_and_solve();
            if (solve_count_match > solve_count)
            {
                solve_count = solve_count_match;
                for (i = 0; i < M_H; i++)
                {
                    for (j = 0; j < M_W; j++)
                    {
                        solve_map[i][j] = map[i][j];
                    }
                }
            }
        }
    }

    /***************************************************************************
    * Set solve map
    ***************************************************************************/
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = solve_map[i][j];
        }
    }
    return solve_count;
}

/*******************************************************************************
* Test function
*******************************************************************************/
void test()
{
    /***************************************************************************
    * Clear map
    ***************************************************************************/
    int i, j;
    for (i = 0; i < M_H; i++)
    {
        for (j = 0; j < M_W; j++)
        {
            map[i][j] = '0';
        }
    }

    /***************************************************************************
    * Test map
    ***************************************************************************/
    int a, b;
    for (a = 0; a < M_H; a++)
    {
        for (b = 0; b < M_W; b++)
        {
            for (i = 0; i < M_H; i++)
            {
                for (j = 0; j < M_W; j++)
                {
                    map[i][j] = '0';
                }
            }
            if (a < M_H - 2 && b < M_W - 1)
            {
                map[a][b] = '1';
                map[a+1][b] = '1';
                map[a+1][b+1] = '1';
                map[a+2][b+1] = '1';
                int m = check_map_and_solve();
                if (m < 436)
                {
                    cout << "At " << m <<": (" << a << "," << b <<")" << endl;
                }
            }
            map[i][j] = '0';
        }
    }

    /***************************************************************************
    * Test map
    ***************************************************************************/
    for (a = 0; a < M_H; a++)
    {
        for (b = 0; b < M_W; b++)
        {
            for (i = 0; i < M_H; i++)
            {
                for (j = 0; j < M_W; j++)
                {
                    map[i][j] = '0';
                }
            }
            if (a > 0 && a < M_H - 1 && b < M_W - 1)
            {
                map[a][b] = '1';
                map[a][b+1] = '1';
                map[a+1][b] = '1';
                map[a+1][b-1] = '1';
                int m = check_map_and_solve();
                if (m < 436)
                {
                    cout << "At " << m <<": (" << a << "," << b <<")" << endl;
                }
            }
            map[i][j] = '0';
        }
    }
}

int main()
{
    /***************************************************************************
    * Test function
    ***************************************************************************/
    test();
    return 0;

    /***************************************************************************
    * Clear map
    ***************************************************************************/
    for (int i = 0; i < M_H; i++)
    {
        for (int j = 0; j < M_W; j++)
        {
            map[i][j] = '0';
        }
    }

    /***************************************************************************
    * Read data from input file
    ***************************************************************************/
    int n = 0;
    ifstream ifs;
    ifs.open("testin.txt");
    if (ifs.is_open())
    {
        while (!ifs.eof())
        {
            int pos = -1;
            ifs >> pos;
            if (pos > 0)
            {
                n++;
                pos--;
                map[pos/M_W][pos%M_W] = '1';
            }
        }
        ifs.close();
    }

    /***************************************************************************
    * Solve this problem
    ***************************************************************************/
    int m = check_map_and_solve();

    /***************************************************************************
    * Write data to output file
    ***************************************************************************/
    ofstream ofs;
    ofs.open("testout.txt");
    if (ofs.is_open())
    {
        for (int i = 0; i < M_H; i++)
        {
            for (int j = 0; j < M_W; j++)
            {
                ofs << map[i][j] << " ";
            }
            ofs << endl;
        }
        ofs << M_H * M_W - n - m << endl;
        ofs.close();
    }

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值