C - Masha and two friends(思维)

C - Masha and two friends

 

1、思路:

最终结果计算所有的白色块的个数,黑色块的个数。

可以只计算白色块的个数,黑色块的个数 = m*n-白色块的个数

题中白色块的数量ans = 第一次被白色覆盖掉的黑色的数量n1 + 第二次被黑色覆盖掉的白色数量n2.

由于两个区间有重合的部分,所以要对重合的部分进行计算。

我们每次刷漆时只考虑纯色覆盖到网格上的情况。

所以,

ans = 给未处理的棋盘刷白漆所覆盖掉的黑色格子的数量nn1 + 给未处理的棋盘刷黑漆所覆盖掉的白色格子的数量nn2 - 给重合

区域刷白漆所覆盖掉的黑色格子的数量nn3。

因为在第二次给棋盘刷漆时,如果不考虑之前白漆的作用,只去掉了棋盘上原本白色的格子,

但是在第一次刷白漆覆盖掉的黑色格子的数量nn3却没有考虑,所以+nn3,就可以了。

 

给出一个矩形两角顶点的坐标,可以求出这个矩形中的黑色格子的数量和白色格子的数量。

从矩形的左下角开始算起,左下角的颜色的数量一定是n*m/2(当n*m为偶数时),或者n*m/2+1(当n*m为奇数时)。

感谢阿力的点拨(*^▽^*)。

 

2、代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL f(LL x1,LL y1,LL x2,LL y2,LL fg){
	LL n = x2-x1+1,m = y2-y1+1;
	if((x1+y1)%2==fg){
		if(n*m%2==0) return n*m/2;
		else return n*m/2+1LL;
	}
	return n*m/2;
}
int main(void){
	int T;
	scanf("%d",&T);
	while(T--){
		LL n,m;
		LL x1,y1,x2,y2;
		LL a1,b1,a2,b2;
		scanf("%lld%lld",&n,&m);
		scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
		scanf("%lld%lld%lld%lld",&a1,&b1,&a2,&b2);
		LL xx1 = max(x1,a1);
		LL yy1 = max(y1,b1);
		LL xx2 = min(x2,a2);
		LL yy2 = min(y2,b2);
		LL W = f(1,1,n,m,0);
		W += f(x1,y1,x2,y2,1);
		W -= f(a1,b1,a2,b2,0);
		//printf("%lld %lld %lld>>>>%lld>\n",f(1,1,n,m,0),f(x1,y1,x2,y2,1),f(a1,b1,a2,b2,0),W);
		if(xx2>=xx1&&yy2>=yy1){
			W -= f(xx1,yy1,xx2,yy2,1);
		}
		LL B = n*m-W;
		printf("%lld %lld\n",W,B);
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值