1 条题解

  • 0
    @ 2025-5-19 16:52:24

    题解思路

    本题需要判断黑方将是否处于“将死”状态,即所有合法移动后的位置均被红方棋子攻击。解题关键在于模拟黑将的所有合法移动,并逐一判断每个新位置是否安全。

    方法思路

    1. 合法移动生成:黑将只能在九宫格((x \in [1,3], y \in [4,6]))内上下左右移动一格,生成所有可能的新位置。
    2. 攻击判定
      • 飞将(红将G):红将与黑将在同一竖线((y)相同)且中间无棋子。
      • 车(R):与黑将在同一行或列,且中间无棋子。
      • 炮(C):与黑将在同一行或列,且中间恰好有一个棋子。
      • 马(H):符合“日”字移动,且“马腿”位置无棋子。
    3. 安全检查:对每个新位置,若未被任何红方棋子攻击,则黑方存在安全移动,直接返回“NO”;若所有移动均被攻击,返回“YES”。

    解决代码

    #include<iostream>
    #include<cstring>
    #include<string>
    using namespace std;
    
    int map[13][13]; //初始化为0,1表示有棋子
    int sign[13][13]; //初始化为0,1表示在红方棋子攻击范围内
    
    struct node
    {
    	char c;
    	int x, y;
    };
    
    int main()
    {
    	int n, bx, by;
    	while (cin >> n >> bx >> by&&n)
    	{
    		memset(map, 0, sizeof(map));           //初始化
    		memset(sign, 0, sizeof(sign));
    		node qizi[10];
    		int rjx, rjy;
    		for (int i = 0; i < n; i++)
    		{
    			cin >> qizi[i].c >> qizi[i].x >> qizi[i].y;
    			if (qizi[i].c == 'G')
    			{
    				rjx = qizi[i].x;
    				rjy = qizi[i].y;
    			}
    			map[qizi[i].x][qizi[i].y] = 1;
    		}
    		
    		if (rjy == by)                              //对特殊情况,黑将和红帅如果直接相对,直接是NO
    		{
    			int ok = 0;
    			for (int i = bx + 1; i < rjx; i++)
    				if (map[i][rjy])
    					ok = 1;
    			if (!ok)
    			{
    				cout << "NO" << endl;
    				continue;
    			}
    		}
    		
    		for (int i = 0; i < n; i++)                  //处理出红方棋子的攻击范围,棋子本身不在其内(可以被吃)
    		{
    			if (qizi[i].c == 'G')                     //处理出将的攻击范围
    			{
    				for (int i = rjx - 1; i >= bx; i--)
    				{
    					sign[i][rjy] = 1;
    					if (map[i][rjy]) break;
    				}
    			}
    			else if (qizi[i].c == 'R')               //处理出车的攻击范围
    			{
    				int xx = qizi[i].x;
    				int yy = qizi[i].y;
    				for (int i = xx + 1; i <= 10; i++)
    				{
    					sign[i][yy] = 1;
    					if (map[i][yy]) break;
    				}
    				for (int i = xx - 1; i >= 1; i--)
    				{
    					sign[i][yy] = 1;
    					if (map[i][yy]) break;
    				}
    				for (int i = yy + 1; i <= 9; i++)
    				{
    					sign[xx][i] = 1;
    					if (map[xx][i]) break;
    				}
    				for (int i = yy - 1; i >= 1; i--)
    				{
    					sign[xx][i] = 1;
    					if (map[xx][i]) break;
    				}
    			}
    			if (qizi[i].c == 'C')                    //处理出炮的攻击范围
    			{
    				int xx = qizi[i].x;
    				int yy = qizi[i].y;
    				int ok;
    				
    				ok = 0;
    				for (int i = xx + 1; i <= 10; i++)
    				{
    					if (ok == 1) sign[i][yy] = 1;
    					if (map[i][yy]) ok++;
    				}
    				
    				ok = 0;
    				for (int i = xx - 1; i >= 1; i--)
    				{
    					if (ok == 1) sign[i][yy] = 1;
    					if (map[i][yy]) ok++;
    				}
    				
    				ok = 0;
    				for (int i = yy + 1; i <= 9; i++)
    				{
    					if (ok == 1) sign[xx][i] = 1;
    					if (map[xx][i]) ok++;
    				}
    				
    				ok = 0;
    				for (int i = yy - 1; i >= 1; i--)
    				{
    					if (ok == 1) sign[xx][i] = 1;
    					if (map[xx][i]) ok++;
    				}
    			}
    			if (qizi[i].c == 'H')                    //处理出马的攻击范围
    			{
    				int xx = qizi[i].x;
    				int yy = qizi[i].y;
    				if (!map[xx - 1][yy])
    				{
    					if (xx - 2 >= 1 && yy - 1 >= 1) sign[xx - 2][yy - 1] = 1;
    					if (xx - 2 >= 1 && yy + 1 <= 9) sign[xx - 2][yy + 1] = 1;
    				}
    				if (!map[xx + 1][yy])
    				{
    					if (xx + 2 <= 10 && yy - 1 >= 1) sign[xx + 2][yy - 1] = 1;
    					if (xx + 2 <= 10 && yy + 1 <= 9) sign[xx + 2][yy + 1] = 1;
    				}
    				if (!map[xx][yy - 1])
    				{
    					if (yy - 2 >= 1 && xx - 1 >= 1) sign[xx - 1][yy - 2] = 1;
    					if (yy - 2 >= 1 && xx + 1 <= 10) sign[xx + 1][yy - 2] = 1;
    				}
    				if (!map[xx][yy + 1])
    				{
    					if (yy + 2 <= 9 && xx - 1 >= 1) sign[xx - 1][yy + 2] = 1;
    					if (yy + 2 <= 9 && xx + 1 <= 10) sign[xx + 1][yy + 2] = 1;
    				}
    			}
    			
    		}
    		
    		
    		
    		
    		
    		int cnt = 0;                       //判断黑将四个方向是否可以走
    		if (bx - 1 >= 1)
    		{
    			if (sign[bx - 1][by])
    				cnt++;
    		}
    		else cnt++;
    		if (bx + 1 <= 3)
    		{
    			if (sign[bx + 1][by])
    				cnt++;
    		}
    		else cnt++;
    		if (by - 1 >= 4)
    		{
    			if (sign[bx][by - 1])
    				cnt++;
    		}
    		else cnt++;
    		if (by + 1 <= 6)
    		{
    			if (sign[bx][by + 1])
    				cnt++;
    		}
    		else cnt++;
    		
    		
    		if (cnt == 4) cout << "YES" << endl;
    		else cout << "NO" << endl;
    	}
    }
    
    • 1

    信息

    ID
    2982
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者