习题4-1(uva-1589)

#include <iostream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>


#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
const int ROW = 11, COL = 10;
const int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int matrix[ROW][COL] = { 0 }, kill[ROW][COL] = {0};
//当前下标是否合法 x -- 1 - 10    y -- 1 - 9
bool IsLegal(int x, int y) {
	if (x <= 0 || y <= 0 || x >= ROW || y >= COL) return false;
	return true;
}
//找下一个自己这方的
int GetLeftRight(int x, int y ,int nAdd) {
	y += nAdd;
	while (y >= 1 && y <= COL - 1 && matrix[x][y] == 0) y += nAdd;
	return y;
}
//找下一个自己这方的
int GetUpDown(int x, int y, int nAdd) {
	x += nAdd;
	while (x >= 1 && x <= ROW - 1 && matrix[x][y] == 0) x += nAdd;
	return x;
}
//增加从x , y 开始能被杀死的次数
void killLine(int x, int y, int c, int flag) {
	//上 
	if (flag == 0) {
		c = max(1, c); x = min(x, COL - 1);
		for (int i = c; i <= x; ++i) kill[i][y]++;
	}
	//下
	else if(flag == 1){
		x = max(1, x); c = min(c, COL - 1);
		for (int i = x; i <= c; ++i)  kill[i][y]++;
	}
	//左
	else if (flag == 2) {
		c = max(1, c); y = min(y, ROW - 1);
		for (int i = c; i <= y; ++i) kill[x][i]++;
	}
	//右
	else if (flag == 3) {
		y = max(1, y); c = min(c, ROW - 1);
		for (int i = y; i <= c; ++i) kill[x][i]++;
	}
}

void KillOne(int x, int y) {
	switch (matrix[x][y])
	{
		//帅
	case 'G': 
	{
	   //向上一个开始 一直到下个自己人 或者越界
		killLine(x-1, y, GetUpDown(x, y, -1), 0);
		break;
	}
	//车
	case 'R':
	{
	//四周扩散
		killLine(x-1, y, GetUpDown(x, y, -1), 0);
		killLine(x+1, y, GetUpDown(x, y, 1), 1);
		killLine(x, y - 1, GetLeftRight(x, y, -1), 2);
		killLine(x, y+1, GetLeftRight(x, y, 1), 3);
		
		break;
	}
	//马
	case 'H':
	{
		int up = x + 1,down = x - 1,left = y - 1,right = y+1;
		//能上下左右跳 到达位置杀死次数+1
		if (matrix[up][y] == 0) {
			int t1 = x + 2, t2 = y - 1;

			if (IsLegal(t1, t2)) kill[t1][t2]++;
			
			t2 = y + 1;if (IsLegal(t1, t2)) kill[t1][t2]++;
		}
		if (matrix[down][y] == 0) {
			int t1 = x - 2,t2 = y - 1;
			if (IsLegal(t1, t2)) kill[t1][t2]++;

			t2 = y + 1;if (IsLegal(t1, t2)) kill[t1][t2]++;
		}
		if (matrix[x][left] == 0) {
			int t1 = x - 1, t2 = y - 2;
			
			if (IsLegal(t1, t2)) kill[t1][t2]++;
			
			t1 = x + 1;if (IsLegal(t1, t2)) kill[t1][t2]++;
		}
		if (matrix[x][right] == 0) {
			int t1 = x - 1, t2 = y + 2;
			if (IsLegal(t1, t2)) kill[t1][t2]++;
			
			t1 = x + 1;if (IsLegal(t1, t2)) kill[t1][t2]++;
		}
		break;
	}
	//炮
	case 'C':
	{
	//隔山打牛  先找山 在找牛 然后打死他
		int up = GetUpDown(x, y, -1); killLine(up - 1, y, GetUpDown(up,y,-1), 0);

		int down = GetUpDown(x, y, 1); killLine(down + 1, y, GetUpDown(down, y, 1), 1);

		int left = GetLeftRight(x, y, -1); killLine(x, left -1, GetLeftRight(x, left, -1), 2);

		int right = GetLeftRight(x, y, 1); killLine(x, right + 1, GetLeftRight(x, right, 1), 3);
		
		break;
	}
	default:
		break;
	}
}


int main()
{
	char ch;
	int n, x, y,a,b;
	while (cin >> n >> x >> y && n) {

		memset(matrix, 0, sizeof(matrix));
		memset(kill, 0, sizeof(kill));

		for (int i = 0; i < n; ++i) {
			cin >> ch >> a >> b;
			matrix[a][b] = ch;
		}
		for (int i = 1; i < ROW; ++i) {
			for (int j = 1; j < COL; ++j) {
				if(!matrix[i][j]) continue;
				KillOne(i, j);
			}
		}
		bool ret = false;
		for (int i = 0; i < 4; ++i) {
			int nx = x + dir[i][0];
			int ny = y + dir[i][1];
			//将能走到的情况下 判断这个位置 是否在 谁的攻击方位 (自己是不能杀自己的) 只要不在别人攻击范围 将就能干掉别人 也就将不死他
			if (nx > 0 && nx <= 3 && ny > 3 && ny <= 6) {
				if (kill[nx][ny] == 0) {
					ret = true;
					break;
				}
			}
		}
		if (ret) cout << "NO" << endl;
		else cout << "YES" << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值