传送门

https://www.cnblogs.com/violet-acmer/p/10146350.html

题意:

  有一块 n*m 的棋盘,初始,黑白块相间排列,且左下角为白块。

  给出两个区间[ (x1,y1) , (x2,y2) ] 和 [ (x3,y3) , (x4,y4) ],第一个区间全部涂成白色,第二个区间全部涂成黑色,且颜色会覆盖。

  求两块区间按照要求涂完后白块和黑快的个数?

题解:

  我的想法如下:

  先求出初始的黑块个数,然后,求出第一个区间减少的黑块个数,再求出第二个区间增加的黑块个数,求出黑块个数后,白块个数也就出来了。

  具体求法:

  

  如何求出初始黑块个数呢?

  定义变量 totBlack 为黑块个数。

  看图,你会发现第一列与第二列黑块的总和 ==8(n)

  也就是说,前m列会有(m/2)*8个黑块,如果m为奇数,那么就会剩下最后一列不能配对,而最后一列的黑块的个数就是 n/2;

  在经过观察,你会发现,黑块的坐标加和 x+y 为奇数,知道这个后,问题将变得异常简单。

  首先[(x1,y1),(x2,y2)]区间1的所有黑块都会被涂成白块,求出此区间的黑块个数 totBlack1,totBlack -= totBlack1;

  而[(x3,y3),(x4,y4)]区间2的所有白块会被涂成黑块,如果区间1和区间2不重合,问题会变得很简单,但,如果重合呢?

  先不考虑重合的问题,单纯的求出区间2的白块个数 totBlack3,totBlack += totBlack3;

  对于重合的部分,求出重合部分的黑块个数 totBlack4,totBlack += totBlack4;

  因为,区间1会把重合部分的黑块变为白块,而区间2在查找白块的时候会忽略重合区间的黑块部分,而这部分正好是少加的。

  具体细节看代码。

  补充一点计算几何的小知识点,如何求出重合矩形?

  

  此题中给的两个坐标正好是左下和右上,很友好,哈哈哈~~~~~~~

AC代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. #define ll __int64
  5.  
  6. ll n,m;
  7. struct Node
  8. {
  9. int x1,y1;
  10. int x2,y2;
  11. Node(int a=,int b=,int c=,int d=)
  12. {
  13. x1=a,y1=b;
  14. x2=c,y2=d;
  15. }
  16. }rec[];
  17.  
  18. //i == 1 : 查找[(x1,y1),(x2,y2)]黑块个数
  19. //i == 2 : 查找[(x3,y3),(x4,y4)]白块个数
  20. //i == 3 : 查找重合区间的黑块个数
  21. ll Find1(int i)
  22. {
  23. int totX=rec[i].x2-rec[i].x1+;
  24. int totY=rec[i].y2-rec[i].y1+;
  25.  
  26. ll res=;
  27. if(totX >= )
  28. res=1ll*totY*(totX>>);
  29. if(totX&)//如果totX为奇数,那么之前两两配对后,会剩下最后一列没被统计
  30. {
  31. if(i&)//查找最后一列黑块个数
  32. {
  33. if(rec[i].x2&)//x2为奇,找y为偶的个数
  34. res += (totY>>)+((totY&) && (rec[i].y1% == ) ? :);
  35. else//x为偶数,找y为奇的个数
  36. res += (totY>>)+((totY&) && (rec[i].y1&) ? :);
  37. }
  38. else//查找最后一列白块个数
  39. {
  40. if(rec[i].x2&)//x2为奇,找y为奇的个数
  41. res += (totY>>)+((totY&) && (rec[i].y1&) ? :);
  42. else//x为偶数,找y为偶的个数
  43. res += (totY>>)+((totY&) && (rec[i].y1% == ) ? :);
  44. }
  45. }
  46. return res;
  47. }
  48. ll Find2()
  49. {
  50. ll res=Find1();
  51. int a=max(rec[].x1,rec[].x1),b=max(rec[].y1,rec[].y1);
  52. int c=min(rec[].x2,rec[].x2),d=min(rec[].y2,rec[].y2);
  53. if(a > c || b > d)
  54. return res;
  55.  
  56. rec[]=Node(a,b,c,d);
  57. res += Find1();//查找重合部分黑块的个数
  58. return res;
  59. }
  60. void Solve()
  61. {
  62. ll totBlack=;
  63. if(m >= )
  64. totBlack=n*(m>>);
  65. totBlack += ((m&) ? (n>>):);
  66.  
  67. totBlack -= Find1();//去掉第一个区间减少的黑块个数
  68. totBlack += Find2();//加上第二个区间增加的黑块个数
  69.  
  70. printf("%I64d %I64d\n",n*m-totBlack,totBlack);
  71. }
  72. int main()
  73. {
  74. int t;
  75. scanf("%d",&t);
  76. while(t--)
  77. {
  78. int a,b,c,d;
  79. scanf("%I64d%I64d",&n,&m);
  80.  
  81. scanf("%d%d%d%d",&a,&b,&c,&d);
  82. rec[]=Node(a,b,c,d);
  83.  
  84. scanf("%d%d%d%d",&a,&b,&c,&d);
  85. rec[]=Node(a,b,c,d);
  86.  
  87. Solve();
  88. }
  89. return ;
  90. }

  这道题,踩了范围的坑!!!!!

  中间定义的一些变量是 int ,但是由于含有乘法操作,中间结果会溢出 int 范围,然后,改了好久好久~~~~~~

  

  一直在wa在text2数据,后来发现,越界了,改成 res=1ll*totY*(totX>>1)才过的

  顶着明天Linux考试要挂科的风险再次码了好久好久代码。。。。

  考前磨磨枪吧,万一过了呢!!!!!!!

  代码有毒,上瘾,哈哈哈,可我就是喜欢啊

Codeforces Round #524 (Div. 2) C. Masha and two friends(思维+计算几何?)的更多相关文章

  1. Codeforces Round #524 (Div. 2) C. Masha and two friends(矩形相交)

    C. Masha and two friends time limit per test 1 second memory limit per test 256 megabytes input stan ...

  2. Codeforces Round #524 (Div. 2) C. Masha and two friends

    C. Masha and two friends 题目链接:https://codeforc.es/contest/1080/problem/C 题意: 给出一个黑白相间的n*m的矩阵,现在先对一个子 ...

  3. Codeforces Round #524 (Div. 2) C. Masha and two friends 几何:判断矩形是否相交以及相交矩形坐标

    题意 :给出一个初始的黑白相间的棋盘  有两个人  第一个人先用白色染一块矩形区域 第二个人再用黑色染一块矩形区域 问最后黑白格子各有多少个 思路:这题的关键在于求相交的矩形区间 给出一个矩形的左下和 ...

  4. Codeforces Round #524 (Div. 2) C. Masha and two friends 思路

    题目:题目链接 思路:直接计数显然是不好处理的,但分情况讨论只要不写错这题是一定可以出的,但这样基本做完这个题就没时间做其他题了,但当时我就这么蠢的这样做了,比赛一个半小时的时候突然发现一个似乎可行的 ...

  5. Codeforces Round #524 (Div. 2)(前三题题解)

    这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...

  6. Codeforces Round #556 (Div. 2) - C. Prefix Sum Primes(思维)

    Problem  Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 1000 mSec Problem Descripti ...

  7. Codeforces Round #524 (Div. 2) Masha and two friends矩形

    题目 题意:    给一个n*m块大的黑白相间的矩形,在这个举行中操作,要先把第一个矩形(左下角坐标(x1,y2),右上角坐标(x2,y2)) 全部涂成白色,再把第二个矩形(左下角坐标(x3,y3), ...

  8. Codeforces Round #524 (Div. 2) F. Katya and Segments Sets(主席树)

    https://codeforces.com/contest/1080/problem/F 题意 有k个区间,区间的种类有n种,有m个询问(n,m<=1e5,k<=3e5),每次询问a,b ...

  9. Codeforces Round #524 (Div. 2) E. Sonya and Matrix Beauty(字符串哈希,马拉车)

    https://codeforces.com/contest/1080/problem/E 题意 有一个n*m(<=250)的字符矩阵,对于每个子矩阵的每一行可以任意交换字符的顺序,使得每一行每 ...

随机推荐

  1. Java HashMap的put操作(Java1.8)

    https://www.cnblogs.com/JzedyBlogs/p/10208295.html 写得非常好: 这个是Java1.8 ------------------------------- ...

  2. Java之指定Junit测试方法的执行顺序举例

    问题描述: 大家都知道使用JUnit进行测试的时候,方法的执行顺序不是按照编写的先后顺序执行的,那么如何控制Junit的执行顺序呢? 解决方法: 在测试类上加 @FixMethodOrder 注解即可 ...

  3. spring @Validated 注解开发中使用group分组校验

    之前知道spring支持JSR校验,在自己定义的bean中加入@NotNull,@NotBlank,@Length等之类的校验用于处理前台传递过来的request请求,避免在写多余的代码去处理. 但是 ...

  4. source 和 .

    Linux Source命令及脚本的执行方式解析 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile 对 ...

  5. BizTalk Server 如何处理大消息

    什么是大消息? 遗憾的是,此问题的答案不而直接与特定的消息大小,绑定,取决于你的 Microsoft 的特定瓶颈 BizTalk Server 系统. 与大消息关联的问题可分为以下几类: 内存不足错误 ...

  6. mybatis,主键返回指的是返回到传入的对象中

  7. [洛谷日报第62期]Splay简易教程 (转载)

    本文发布于洛谷日报,特约作者:tiger0132 原地址 分割线下为copy的内容 [洛谷日报第62期]Splay简易教程 洛谷科技 18-10-0223:31 简介 二叉排序树(Binary Sor ...

  8. 最简单的Spring Security配置示例

    代码结构: pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...

  9. Git——入门操作加创建账号【三】

    创建账号 GitHub https://github.com/ 码云 https://gitee.com/ 无论是github还是码云,创建账号都是非常简单快捷的,大家可以自行选择创建下,不过建议最好 ...

  10. [SCOI2005] 互不侵犯

    传送门:>Here< 解题思路 其实这道题一种很简单的解法是搜索+打表,但是这样很赖皮.这里给出一种状压DP的解法. 很显然利用普通的DP无法解决了,因为针对点来转移是很难的.但看到$N& ...