【LGR-070】洛谷 3 月月赛 I & EE Round 1 Div.2

【LGR-070】洛谷 3 月月赛 I & EE Round 1 Div.2

A 苏联人 入门

题目描述

你在打EE Round 1, 发现第一题非常无聊, 于是你不打了, 去下国际象棋了。
结果你发现, 由于某种神秘力量的影响, 你的棋子只剩下若干黑色的战车, 若干黑色的主教, 和一只白色的国王了。
由于你很无聊, 所以你把一些棋子放在了 8 × 8 8 \times 8 8×8的棋盘上。
由于你很无聊, 所以你想知道, 国王放在哪些格子上是安全的。 换句话说, 有哪些各自不会被战车和主教攻击到。 当然国王不能放在已经有棋子的地方
为了防止你无聊透顶而不知道国际象棋的规则, 这里给出以下提示(如果你知道规则可以跳过)
国际象棋中, 战车可以横向、竖向移动, 且格数不受限制。但不能越过其他棋子
哈哈哈哈
如图, 黄色的格子为战车能走到(攻击到的)格子。
国际象棋中, 主教可以斜向移动, 且格数不受限制, 但不能越过其他棋子
在这里插入图片描述

如图, 黄色的各自为主教能走到(攻击到)的格子。
简单来说, 如果当前位置到目标位置的直线上存在其他棋子, 则可以称为”越过了其他棋子“。
如果目标位置是对方的棋子, 那么移动到目标位置后, 对方的棋子会被吃掉
更进一步的, 你要找的所有位置, 必须满足没有黑色棋子能一步走到。

题目分析

1.有棋子

不能

2.主教

四条直线分别是x-k, y-k;x-k, y+k;x+k, y-k;x+k, y+k;
如果途中途碰到棋子, 那么这条线就失效了, break;

3.战车;

四条线分别是:x, y-k; x, y+k, x+k, y; x-k, y;
棋子处理一样;

代码

for(int i = 1; i <= 8; i++)
{
   
	for(int j = 1; j <= 8; j++)
	{
   
		cin >> a[i][j];
		p[i][j] = true;
		if(a[i][j] == '.')
		{
   
			continue;
		}
		else
		{
   
			p[i][j] = false;
		}
	}
}
for(int i = 1; i <= n; i++)
{
   
	for(int j = 1; j <= n; j++)
	{
   
		if(a[i][j] == 'B')
		{
   
			for(int k = 1; i-k && j-k; k++)
			{
   
				if(a[i-k][j-k] != '.')
				{
   
					break;	
				}
				p[i-k][j-k] = false;
			}
			for(int k = 1; i-k && j+k <= 8; k++)
			{
   
				if(a[i-k][j+k] != '.')
				{
   
					break;
				}
				p[i-k][j+k] = false;
			}
			for(int k = 1; i+k <= 8 && j-k; k++)
			{
   
				if(a[i+k][j-k] != '.')
				{
   
					break;
				}
				p[i+k][j-k] = false;
			}
			for(int k = 1; i+k <= 8; j+k <= 8; k++)
			{
   
				if(a[i+k][j+k] !='.')
				{
   
					break;
				}
				p[i+k][j+k] = false;
			}
		}
		if(a[i][j] == 'R')
		{
   
			for(int k = 1; j-k ; k++)
			{
   
				if(a[i][j-k] != '.')
				{
   
					break;
				}
				p[i][j-k] = false;
			}
			for(int k = 1; i-k; k++)
			{
   
				if(a[i-k][j] != '.')
				{
   
					break;
				}
				p[i][j-k] = false;
			}
			for(int k = 1; i+k <= 8; k++)
			{
   
				if(a[i+k][j] != '.')
				{
   
					break;
				}
				p[i+k][j] = false;
			}
			for(int k = 1; j + k <= 8; k++)
			{
   
				if(a[i][j+k] != '.')
				{
   
					break;
				}
				p[i][j+k] = false;
			}
		}
	}
}
for(int i = 1; i <= 8; i++)
{
   
	for(int j = 1; j <= 8; j++)
	{
   
		if(p[i][j] == true)
		{
   
			cout << 1;
		}
		else
		{
   
			cout << 0;
		}
	}
	cout << endl;
}
				

B 迫害 普及

题目描述

有k个人, X要对这k个人进行迫害。
这k个人, 每个人都拥有一个数字, 分别从1至k。
X拥有n+m个数字, 这些数字为n个1, 和m个大小可有X决定的数字(每个数字定好后就不能再更换。
X能对这些人进行迫害, 当且仅当他能用手中若干个数的加和等于呗迫害人的数字, 一次迫害就成功了(不会消耗数字)。
由于X权力极大, 又十分邪恶, 他想要从第1个人开始一个一个进行迫害行动。
由于小Z也在这个被迫害的行列里, 他十分的慌张, 希望你来告诉他X能最多能从第一个人开始连续迫害多少个人。
由于被迫害的人太多了, 他十分的慌张, 希望你来告诉他最多能从第一个人开始连续迫害多少个人。
由于被迫害的人太多了, 所以请将答案对1000000007取模;

题目分析

首先, 现在有N个1, 就可以连续迫害N个人,编号从1~N;
现在后面自己选择的数字有两种选择, 第1种:在1~N范围内。第2种, 大于N;
首先明白, 每个选择的数和N个1组合共可以形成N+1个不同的数 (也可以只选自己而不选1)
因为要迫害最多的人, 而且现在1~N已经被迫害了, 所以形成的这N+1个数尽量在N之外去迫害新的人。
又发现, 当选的数大于N的时候。它与N个1组合形成的N+1个数全都能迫害一个新的编号的人。所以第2种数字选择比第1种更优。
又因为必须是连续迫害, 所以我们第一个选择的数必须是N+1, 设这个数能迫害 m 1 m_1 m

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值