zoukankan      html  css  js  c++  java
  • sicily 1172. Queens, Knights and Pawns

    Description

    You all are familiar with the famous 8-queens problem which asks you to place 8 queens on a chess board so no two attack each other. In this problem, you will be given locations of queens and knights and pawns and asked to find how many of the unoccupied squares on the board are not under attack from either a queen or a knight (or both). We'll call such squares "safe" squares. Here, pawns will only serve as blockers and have no capturing ability. The board below has 6 safe squares. (The shaded squares are safe.) 



    Recall that a knight moves to any unoccupied square that is on the opposite corner of a 2x3 rectangle from its current position; a queen moves to any square that is visible in any of the eight horizontal, vertical, and diagonal directions from the current position. Note that the movement of a queen can be blocked by another piece, while a knight's movement can not.

    Input

    There will be multiple test cases. Each test case will consist of 4 lines. The first line will contain two integers n and m, indicating the dimensions of the board, giving rows and columns, respectively. Neither integer will exceed 1000. The next three lines will each be of the form 
    k r1 c1 r2 c2 ... rk ck 
    indicating the location of the queens, knights and pawns, respectively. The numbering of the rows and columns will start at one. There will be no more than 100 of any one piece. Values of n = m = 0 indicate end of input.

    Output

    Each test case should generate one line of the form 
    Board b has s safe squares. 
    where b is the number of the board (starting at one) and you supply the correct value for s.

    Sample Input
     Copy sample input to clipboard 
    4 4
    2 1 4 2 4
    1 1 2
    1 2 3
    2 3
    1 1 2
    1 1 1
    0
    1000 1000
    1 3 3
    0
    0
    0 0
    
    Sample Output
    Board 1 has 6 safe squares.
    Board 2 has 0 safe squares.
    Board 3 has 996998 safe squares.
    这题可能有理解错误的地方就是对queen,它在八个方向的移动是不限的,除非遇到一个其他对象。
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    char location[1001][1001];
    
    int king[16] = {-2, -1, -2, 1, -1, 2, 1, 2, 2, 1, 2, -1, 1, -2, -1, -2};
    int queueL[16] = {-1, -1, -1, 0, -1, 1, 0, -1, 0, 1, 1, -1, 1, 0, 1, 1};
    
    int main(int argc, char const *argv[])
    {
        int m, n, num, x, y;
        int testCase = 0;
        while (cin >> m >> n && m != 0 && n != 0) {
            ++testCase;
            memset(location, '0', sizeof(location));
            vector<int> queue;
    
            // queen
            cin >> num;
            queue.resize(num * 2 + 1);
            int i = 0, j = 0;
            while (i++ < num) {
                cin >> x >> y;
                location[x - 1][y - 1] = '2';
                queue[j] = x - 1;
                queue[j + 1] = y - 1;
                j += 2;
            }
    
            // knight
            i = 0;
            cin >> num;
            while (i++ < num) {
                cin >> x >> y;
                location[x - 1][y - 1] = '2';
                for (int k = 0; k < 16; k += 2) {  // 处理8个方向,也即八个“日”字形路线
                    int xT = x - 1 + king[k];
                    int yT = y - 1 + king[k + 1];
                    if (xT >= 0 && xT < m && yT >= 0 && yT < n && location[xT][yT] == '0')
                        location[xT][yT] = '1';
                }
            }
    
            // pawn
            i = 0;
            cin >> num;
            while (i++ < num) {
                cin >> x >> y;
                location[x - 1][y - 1] = '2';
            }
    
            // Queen 的处理
            for (i = 0; i < j; i += 2) {
                for (int p = 0; p < 16; p += 2) {
                    int xT = queue[i];
                    int yT = queue[i + 1];
                    for (int q = 0; ; ++q) {
                        xT += queueL[p];
                        yT += queueL[p + 1];
                        if (xT >= 0 && xT < m && yT >= 0 && yT < n && location[xT][yT] == '0') {
                            location[xT][yT] = '1';
                        } else if (xT >= 0 && xT < m && yT >= 0 && yT < n && location[xT][yT] == '2') { // 在该直线上遇到了其他对象,所以不需要再走了
                            break;
                        } else if(xT < 0 || xT >= m || yT < 0 || yT >= n) {  // 跑出了棋盘,那么说明在这条直线上已经不需要再走了
                            break;
                        }
                    }
                }
            }
    
            int result = 0;
            for (i = 0; i != m; ++i) {
                for (j = 0; j != n; ++j)
                    if (location[i][j] == '0')
                        ++result;
            }
    
            cout << "Board " << testCase << " has " << result << " safe squares." << endl;
        }
        return 0;
    }
  • 相关阅读:
    已安装 SQL Server 2005 Express 工具。若要继续,请删除 SQL Server 2005 Express 工具
    超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
    C#微信公众号开发 -- (七)自定义菜单事件之VIEW及网页(OAuth2.0)授权
    C#微信公众号开发 -- (六)自定义菜单事件之CLICK
    C#微信公众号开发 -- (五)自定义菜单创建
    C#微信公众号开发 -- (四)获取API调用所需的全局唯一票据access_token
    C#微信公众号开发 -- (三)用户关注之后自动回复
    C#微信公众号开发 -- (二)验证成为开发者
    linux下删除大量文件提示参数过长解决办法
    Linux 远程连接sftp与ftp
  • 原文地址:https://www.cnblogs.com/xiezhw3/p/4051891.html
Copyright © 2011-2022 走看看