sicily 1172 Queens, Knights and Pawns

题目意思:

类似于八皇后问题,但不是放置皇后,是计算安全位置。有三种棋子,皇后、骑士和卒(pawn,貌似不是这个意思)。皇后是全方向攻击(八个方向),距离不限,但是会被阻挡;骑士只能走“日”字形,也有八个方向,不受阻挡;卒子不能动。然后计算整个棋盘的安全位置(皇后和骑士都无法攻击到的位置)。

解题思路:

最简单的,逐个遍历皇后和骑士(卒子不能攻击当然先忽略),然后记录该棋子的能攻击的位置,到最后统计没有记录的格子就是安全格子数。

曾经想过用计算几何的方法,把皇后的轨迹当直线,后来又懒得写,不过感觉不行。

代码:

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

int qs;
int que[ 101 ][ 2 ];
int ks;
int kni[ 101 ][ 2 ];
int ps;
int paw[ 101 ][ 2 ];
char state[ 1001 ][ 1001 ];

int qd[ 8 ][ 2 ] = { -1, 0, -1, 1, 0, 1, 1, 1, 1, 0, 1, -1, 0, -1, -1, -1 };
// 计算所有皇后能吃到的格子
int calq( int row, int col )
{
	int i, j, r, c;
	int num = 0;
	for( i = 0; i < qs; i++ )
	{
		// 循环八个方向
		for( j = 0; j < 8; j++ ){
			r = que[ i ][ 0 ] + qd[ j ][ 0 ]; // 皇后呀
			c = que[ i ][ 1 ] + qd[ j ][ 1 ];
			while( ( r > 0 && r <= row ) && ( c > 0 && c <= col ) )
			{
				// 有阻挡
				if( state[ r ][ c ] > 1 )
					break;
				// 标记访问
				if( state[ r ][ c ] < 1 ){
					state[ r ][ c ] = 1;
					num++;
				}
				r += qd[ j ][ 0 ];
				c += qd[ j ][ 1 ];
			}
		}
	}
	return num;
}

int kd[ 8 ][ 2 ] = { -2, 1, -1, 2, 1, 2, 2, 1, 2, -1, 1, -2, -1, -2, -2, -1};
// 计算所有骑士能吃到的格子
int calk( int row, int col )
{
	int i, j, r, c;
	int num = 0;
	for( i = 0; i < ks; i++ )
	{
		// 遍历八个方向
		for( j = 0; j < 8; j++ )
		{
			r = kni[ i ][ 0 ] + kd[ j ][ 0 ]; // 骑士呀
			c = kni[ i ][ 1 ] + kd[ j ][ 1 ];
			// 不会阻挡
			if( ( r > 0 && r <= row ) && ( c > 0 && c <= col ) ){
				if( state[ r ][ c ] < 1 ){
					state[ r ][ c ] = 1;
					num++;
				}
				r += kd[ j ][ 0 ];
				c += kd[ j ][ 1 ];
			}
		}
	}
	return num;
}

int main()
{
	int row, col, i;
	int r, c;
	int times = 0;
	while( cin >> row >> col )
	{
		if( row + col == 0 )
			break;
		times++;
		memset( state, 0, sizeof( state ) );
		
		// 读入皇后
		cin >> qs;
		for( i = 0; i < qs; i++ )
		{
			cin >> r >> c;
			que[ i ][ 0 ] = r;
			que[ i ][ 1 ] = c;
			state[ r ][ c ] = 3;
		}
		// 读入骑士
		cin >> ks;
		for( i = 0; i < ks; i++ )
		{
			cin >> r >> c;
			kni[ i ][ 0 ] = r;
			kni[ i ][ 1 ] = c;
			state[ r ][ c ] = 3;
		}
		// 读入pawn
		cin >> ps;
		for( i = 0; i < ps; i++ )
		{
			cin >> r >> c;
			paw[ i ][ 0 ] = r;
			paw[ i ][ 1 ] = c;
			state[ r ][ c ] = 3;
		}

		int number = row * col - qs - calq( row, col ) - ks - calk( row, col ) - ps;
		cout << "Board " << times << " has " << number << " safe squares." << endl;
	}
	return 0;
}

时间:0.01s 应该还算及格吧。

1、因为题目空间给出的要求有64M,比较多,所以可以稍微浪费点使用,例如说那个数组int kd[ 8 ][ 2 ] = { -2, 1, -1, 2, 1, 2, 2, 1, 2, -1, 1, -2, -1, -2, -2, -1};,这样做有助于节省一点判断时间;

2、个人犯糊涂,把变量名搞错,WA了两三次。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值