title: codeforces-1080C

date: 2018-11-25 14:23:53

tags:

  • acm
  • 刷题

    categories:
  • Codeforces

https://www.cnblogs.com/31415926535x/p/10016085.html

概述

昨天正好有时间,做了自己第一场的cf

做完AB之后被C卡到最后,,,从来没做过坐标平面上两个矩形的面积和,,,因为存在相交的可能,,,所以要单独的处理矩形面积交,,然后自己就写懵了,,,当时写了几十行的if判断,,,,到最后都没弄完,,QAQ

题意与分析

题意

这道题的题意就是给你一个n * m大的方格板子,,类似国际象棋那样,,黑白相间,,然后再给你两个矩形,,第一个矩形内的所有格子涂为白色,,第二个涂为黑色,,,问你最后白格子和黑格子的数量,,棋盘的大小可能是1e9 * 1e9的,,,

思路

我的思路

  • 一开始我的思路是算出所有的白格子,黑格子的数量(wsum ,bsum),,,然后wsum加上第一个矩形里的所有黑格子数量,,之后wsum减去第二个矩形里白格子的数量,,,最后再考虑是有面积的相交,,,有的话再计算相交矩形内的,,但是中间的一些细节,,,比如说如何计算不同左下角坐标的矩形内格子数,,如何判是否有相交的矩形,,如何计算相交的矩形内的格子数量以及怎么调整等等,,,以前从来没写过没考虑过,,,只能硬头皮的去一路if下去,,,到最后自己的写懵了,,,
  • 中途想着直接模拟算了,,,维护一个大矩阵,,1表示白色0表示黑色,,然后对相应的矩形全部置一置零,,,最后求01的数量,,,然后发现根本开不了那么大的数组,,,,QAQ

最后今天看了出题人的题解,,,

矩形(1 , 1 , x , y)内白格子的数量的计算

\(设函数w(x , y)返回值为左下角(1 , 1)与(x , y)的矩形内的白格子的数量\)

矩形内白格子数量的计算

\(任意一个矩形(x_1 , y_1 , x_2 , y_2)内的白格子数量=矩形(1 , 1 , x_2 , y_2)内白格子的数量-矩形(1 , 1 , x_1 , y_2)内白格子的数量-矩形(1 , 1 , x_2 , y_1)内白格子的数量+矩形(1 , 1 , x_1 - 1 , y_1 - 1)内白格子的数量,所以:\)

\[W(x_1 , y_1 , x_2 , y_2) = w(x_1 , y_1) - w(x_1 - 1 , y_2) - w(x_2 , y_1 - 1) + w(x_1 - 1 , y_1 - 1)
\]

矩形内黑格子数量的计算

\[B(x_1 , y_1 , x_2 , y_2) = (x_2 - x_1 + 1) * (y_2 - y_1 + 1) - W(x_1 , y_1 , x_2 , y_2)
\]

相交部分的判断和处理

出题人说显然(我(/‵Д′)/~ ╧╧)如果不存在相交矩形,,那么一定满足

\[max(x_1 , x_3)>min(x_2 , x_4) \ \ or\ \ max(y_1,y_3)>min(y_2,y_4)
\]

所以反命题就是如果存在相交举证即使上面那个判断取反,,同时相交矩形的坐标是

\[(max(x_1 , x_3) \ , \ max(y_1 , y_3)\ ,\ min(x_2,x_4)\ ,\ min(y2 , y_4))
\]

有了这些,,我们就可以算出相交矩形内原来的白色、黑色的格子了(就是不考虑第一个第二个矩形影响时的数量),,

因为在第一个矩形里将相交矩形内的黑格子变成了白色,,现在又要变成黑色,,所以wsum(白色格子的数量)要减去黑色的数量(白色的数量已经在计算第二个矩形时减去了,,所以对于wsum是减去了相交矩形的所有格子数量),,同时黑色格子的数量bsum要加上黑色的数量,,而计算第二个矩形时相交矩形里的白色已经加上了,,,相当于加上了整个相交矩形的格子数量,,(拿笔画一下这个步骤就更清楚了)

w(x , y)的实现

首先我们定义这样排列的黑白格子为类型1



而这样的是类型2

  • 行数n为偶数时,类型1类型2的数量是对半的,即\(\frac n2\),

  • 行数n为奇数时,类型1的数量是\(\lfloor{\frac n2}\rfloor\) (向下取整,直接除就行),,类型2的数量是\(\lceil{\frac n2}\rceil\)(向上取整,有余数时加一个)

因为行数n为偶数时类型1的数量和类型2数量相等,也就是说\(\lfloor{\frac n2}\rfloor\)=\(\lceil{\frac n2}\rceil\),,所以,,我们就不管行数是不是偶数奇数了,,,直接类型1数量=\(\lfloor{\frac n2}\rfloor\),类型2数量=\(\lceil{\frac n2}\rceil\),,,(数学真好玩.jpg,,,想想我当时为了判断行数的奇偶分情况讨论,,写吐ed,,(#`Д´)ノ)

按照这个思路,,,同样列数m也就可以这样计算了,,,

类型1的数量=\(\lfloor{\frac m2}\rfloor\),,类型2的数量=\(\lceil{\frac m2}\rceil\)..

有了这两个,,我们就可以计算矩形(x , y)内了白色格子的数量了,,,

\[w(x , y) = \lceil{\frac n2}\rceil \cdot \lceil{\frac m2}\rceil + \lfloor{\frac n2}\rfloor \cdot \lfloor{\frac m2}\rfloor
\]

向上取整的实现

这道题除了让我知道矩形交的处理,,,还有一个从好几个大佬的代码中我看到了几个好的求向上取整的代码,,,不像我那样傻傻的if判断(╬☉д⊙)

ll cdiv(ll a , llb)
{
return a / b + (a % b > 0);
}
//or
ll cdiv(ll a , ll b)
{
return (a + b - 1) / b;
}

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//ceiling div
ll cdiv(ll a , ll b)
{
return a / b + (a % b > 0);
}
ll ccdiv(ll a , ll b)
{
return (a + b - 1) / b;
}
ll w(ll x , ll y)
{
return cdiv(x , 2) * cdiv(y , 2) + (x / 2) * (y / 2);
}
ll wsum(ll x1 , ll y1 , ll x2 , ll y2)
{
return w(x2 , y2) - w(x1 - 1 , y2) - w(x2 , y1 - 1) + w(x1 - 1 , y1 - 1);
}
ll bsum(ll x1 , ll y1 , ll x2 , ll y2)
{
return (x2 - x1 + 1) * (y2 - y1 + 1) - wsum(x1 , y1 , x2 , y2);
}
int main()
{
//freopen("233.txt" , "r" , stdin);
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int t;cin >> t;
while(t--)
{
ll n , m;
cin >> n >> m;
ll x1 , x2 , x3 , x4 , y1 , y2 , y3 , y4;
cin >> x1 >> y1 >> x2 >> y2;
cin >> x3 >> y3 >> x4 >> y4;
ll w = wsum(1 , 1 , m , n);
ll b = bsum(1 , 1 , m , n);
//first rec
w = w + bsum(x1 , y1 , x2 , y2);
b = b - bsum(x1 , y1 , x2 , y2);
//second rec(dont consider the itersection
w = w - wsum(x3 , y3 , x4 , y4);
b = b + wsum(x3 , y3 , x4 , y4);
//consider the itersection
if(max(x1 , x3) <= min(x2 , x4) && max(y1 , y3) <= min(y2 , y4))
{
w = w - bsum(max(x1 , x3) , max(y1 , y3) , min(x2 , x4) , min(y2 , y4));
b = b + bsum(max(x1 , x3) , max(y1 , y3) , min(x2 , x4) , min(y2 , y4));
}
cout << w << " " << b << endl;
}
}

小结

  • 一直不怎么会的向上取整、矩形面积交等等问题算是了解了,,,至少不会在出现的时候啥都不知道,,只能从头分析,,,一个劲的堆if了(-`ェ´-╬)
  • cf真好玩.jpg,,,以为会第一发只能灰名,,没想到青了,,,就是深夜场太多,,,不然能天天打,,,,
  • 这种代码不多的题锻炼锻炼思维很不错啊,,,毕竟现在纯套板子的题在各种比赛中是越来越少了,,,,
  • 不知道这里的数学公式显示的如何,,,全是按原博客的规则写的啊QAQ

    (end)

codeforces-1080C的更多相关文章

  1. Codeforces 1080C 题解(思维+二维前缀和)

    题面 传送门 题目大意: 有一个黑白的棋盘,现在将棋盘上的一个子矩形全部染成黑色,另一个子矩形全部染成白色 求染完色后黑,白格子的总数 分析 我们可以发现,对于一个(1,1)到(x,y)的矩形,若xy ...

  2. Codeforces Round #524 (Div. 2) codeforces 1080A~1080F

    目录 codeforces1080A codeforces 1080B codeforces 1080C codeforces 1080D codeforces 1080E codeforces 10 ...

  3. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  4. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  5. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  6. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  7. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  8. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  9. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  10. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. SSM框架的搭建与测试

    关于框架的搭建无非就是 框架所依赖的jar包,然后就是关于各个框架的配置文件: 下面我们来看下不同层的依赖的jar包以及各个配置文件: 首先pojo这一层只需要依赖parent聚合工程 mapper层 ...

  2. HDU 3511 圆扫描线

    找最深的圆,输出层数 类似POJ 2932的做法 圆扫描线即可.这里要记录各个圆的层数,所以多加一个维护编号的就行了. /** @Date : 2017-10-18 18:16:52 * @FileN ...

  3. Asp.net 子web application的Session共享

    需求提出: 网站: 父Web Application: http://www.test.com/ 子Web Application 1: http://www.test.com/child1 子Web ...

  4. 第一、介绍Canvas

    canvas能做什么? canvas是HTML5中的新元素,你可以使用javascript用它来绘制图形.图标.以及其它任何视觉性图像.它也可用于创建图片特效和动画.如果你掌握了完整的命令,你可以用c ...

  5. jquery操作select(取值,设置选中)[转]

    每一次操作select的时候,总是要出来翻一下资料,不如自己总结一下,以后就翻这里了. 比如<select class="selector"></select&g ...

  6. [python]小技巧集锦

    1.数组过滤,只适用于numpy alpha[alpha>0]:返回alpha中大于0的元素组成的数组 2.在范围内选取不等于某值的数值 j = i while j==i: j = int(ra ...

  7. 【转】在Mac OS X 10.8中配置Apache + PHP + MySQL

    CHENYILONG Blog 在Mac OS X 10.8中配置Apache + PHP + MySQL 在Mac OS X 10.8中配置Apache+PHP+MySQL的内容包括: 配置Apac ...

  8. JavaScript 计时

    http://www.w3school.com.cn/js/js_timing.asp JavaScript 计时事件 通过使用 JavaScript,我们有能力作到在一个设定的时间间隔之后来执行代码 ...

  9. 转载 你不知道的super

    http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...

  10. 在线建立或重做mysql主从复制架构方法(传统模式和GTID模式)【转】

    mysql主从复制架构,是mysql数据库主要特色之一,绝大多数公司都有用到. 而GTID模式是基于事务的复制模式的意思,发展到现在也是越来越多人用. 以前很多文章,介绍搭建mysql主从复制架构,是 ...