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

来源:互联网 发布:软件过程规范名词解释 编辑:程序博客网 时间:2024/04/29 05:01

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;}

 

原创粉丝点击