暴力什么的就算了,贪心他不香吗

这题其实如果分开想,就三种情况需要讨论:(由于不会发图,只能手打

1)

5 . . . . .

4 . . . . .

3 . . . H .

2 . . G . .

1 . H . . .

0 1 2 3 4 5

在这种情况下,下面两个H绝对不在一组(因为他们中有G)

2)

5 . . G . .

4 . . H . .

3 . . . H .

2 . H . . .

1 . G . . .

0 1 2 3 4 5

在这种情况下所有H都能拿,因为G在所有H之上/之下

3)

5 . . H . .

4 . . G . .

3 . . . H .

2 . . . . H

1 . H . . .

0 1 2 3 4 5 在这种情况下下面所有H都能拿,但是上面那个连不了(被G挡住了)

因此,我们只需要对这三种情况进行判断就行了(判断方法见注释)

  1. pp find_pair(int aa, int bb){
  2. int mini = 1e8,maxi = 0;
  3. int low = aa, high = bb;
  4. while(cow[low-1].x==cow[aa].x) {low--;if (low==0)break;}
  5. while(cow[high-1].x==cow[bb].x) {high++; if (high == 0) break;}
  6. //这是一个很重要的判断:
  7. //因为我们在排序的时候有可能遇到x相等的点,这个点并不会被搜索,但是这个点仍然需要判断。在这个时候就需要往前和后搜索x相等的点
  8. for (int i=low;i<=high;i++){
  9. if (cow[i].id=='G'){
  10. if (cow[i].y>max(cow[aa].y,cow[bb].y)) mini = min(mini,cow[i].y);
  11. else if (cow[i].y<min(cow[aa].y,cow[bb].y)) maxi = max(maxi,cow[i].y);
  12. else posible = false;
  13. }
  14. }//如果这两个点中间有G就进行以下判断:
  15. //1.如果这个G的y坐标在这两个点的y之上,那么我们将最高值更新
  16. //2.如果这个G的坐标在y之下,我们将最小值之下,我们更新最小值
  17. //3.如果这个G在两个坐标中间,那么这两个点必然不可能选(因为无论怎么样连最后G都会在这个范围里)
  18. return make_pair(mini,maxi);
  19. }

那么问题来了,怎么保证找的G在两个H的中间呢?

还用问吗,加个sort就好了

*注意事项:在找G的时候,我们要记住如果这个G和H的x坐标相等,在sort的时候未必会在他的范围内。那怎么办?

还用问吗,如果x坐标相等就减/加到他不相等为止

  1. while(cow[low-1].x==cow[aa].x) {low--;if (low==0)break;}
  2. while(cow[high-1].x==cow[bb].x) {high++; if (high == 0) break;}

找完G之后,我们对两点之间的所有H进行判断:

如果这个H在上下G的y的范围以内,那么我们更新最大/最小值。(相当于更新高)

  1. pp in_range(int aa, int bb, pp bo){
  2. int maxi = 0,mini = 1e8;
  3. for (int i=aa;i<=bb;i++){
  4. if (cow[i].id!='G'){
  5. if (between(bo,cow[i].y)){
  6. maxi = max(maxi,cow[i].y);
  7. mini = min(mini,cow[i].y);
  8. temp++;
  9. }
  10. }
  11. }//现在已经找出了在这个点上面最低的G点和下面最高的G点
  12. //我们在这个范围里面搜索所以的H,更新最高点和最低点(前提是要在G点的范围内)
  13. return make_pair(maxi,mini);
  14. }

找完之后怎么办?

还用问吗,当然找面积啊

面积 = 底*高 = (x2-x1)*abs(y2-y1) [因为sort了,所以x2一定>=x1]

  1. if (temp){
  2. if(temp>breed){
  3. //如果H的数量大于之前的,直接更新
  4. breed = temp;
  5. ans = abs(res.first-res.second)*abs(cow[j].x-cow[i].x);
  6. }else if (temp==breed) ans = min(ans,abs(res.first-res.second)*abs(cow[j].x-cow[i].x));//否则更新面积(底『x的差』乘高『最高y值和最低y值的差』
  7. }

由于判断不需要储存,这个程序用500的空间其实就够了(800-KB应该够小了吧)

完整代码如下:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <math.h>
  4. #include <stdio.h>
  5. using namespace std;
  6. #define pp pair<int,int>
  7. struct node{
  8. int x,y;
  9. char id;
  10. }cow[505];
  11. int tot = 0, temp = 0;
  12. int a,b,c; char d;
  13. void add(int aa, int bb, char cc){
  14. cow[++tot].x = aa;
  15. cow[tot].y = bb;
  16. cow[tot].id = cc;
  17. }
  18. bool sorted(node aa, node bb){
  19. return aa.x<bb.x;
  20. }
  21. bool between(pp aa,int b){
  22. return aa.first>b && aa.second<b;
  23. }//这个是表示一个数是否在两个数直接
  24. bool posible = true;
  25. pp find_pair(int aa, int bb){
  26. int mini = 1e8,maxi = 0;
  27. int low = aa, high = bb;
  28. while(cow[low-1].x==cow[aa].x) {low--;if (low==0)break;}
  29. while(cow[high-1].x==cow[bb].x) {high++; if (high == 0) break;}
  30. //这是一个很重要的判断:
  31. //因为我们在排序的时候有可能遇到x相等的点,这个点并不会被搜索,但是这个点仍然需要判断。在这个时候就需要往前和后搜索x相等的点
  32. for (int i=low;i<=high;i++){
  33. if (cow[i].id=='G'){
  34. if (cow[i].y>max(cow[aa].y,cow[bb].y)) mini = min(mini,cow[i].y);
  35. else if (cow[i].y<min(cow[aa].y,cow[bb].y)) maxi = max(maxi,cow[i].y);
  36. else posible = false;
  37. }
  38. }//如果这两个点中间有G就进行以下判断:
  39. //1.如果这个G的y坐标在这两个点的y之上,那么我们将最高值更新
  40. //2.如果这个G的坐标在y之下,我们将最小值之下,我们更新最小值
  41. //3.如果这个G在两个坐标中间,那么这两个点必然不可能选(因为无论怎么样连最后G都会在这个范围里)
  42. return make_pair(mini,maxi);
  43. }
  44. pp in_range(int aa, int bb, pp bo){
  45. int maxi = 0,mini = 1e8;
  46. for (int i=aa;i<=bb;i++){
  47. bool update = true;
  48. while(update){
  49. if (cow[i].id!='G'){
  50. if (between(bo,cow[i].y)){
  51. maxi = max(maxi,cow[i].y);
  52. mini = min(mini,cow[i].y);
  53. temp++;
  54. }
  55. }
  56. }
  57. }//现在已经找出了在这个点上面最低的G点和下面最高的G点
  58. //我们在这个范围里面搜索所以的H,更新最高点和最低点(前提是要在G点的范围内)
  59. return make_pair(maxi,mini);
  60. }
  61. int main(){
  62. ios::sync_with_stdio(0);
  63. cin >> a;
  64. for (int i=0;i<a;i++){
  65. cin >> b >> c >> d;
  66. add(b,c,d);
  67. }
  68. int ans = 0, breed = 1;
  69. sort(cow+1,cow+tot+1,sorted);
  70. //以上不解释
  71. for (int i=1;i<=a;i++){
  72. for (int j=i+breed;j<=a;j++){
  73. if (cow[i].id=='G'||cow[j].id == 'G') continue;//如果两个点中有G就不需要判断
  74. posible = true;
  75. temp = 0;
  76. pp bounds = find_pair(i,j);//先找G的范围
  77. if (!posible) continue;
  78. pp res = in_range(i,j,bounds);//再找H的范围
  79. if (temp){
  80. if(temp>breed){
  81. //如果H的数量大于之前的,直接更新
  82. breed = temp;
  83. ans = abs(res.first-res.second)*abs(cow[j].x-cow[i].x);
  84. }else if (temp==breed) ans = min(ans,abs(res.first-res.second)*abs(cow[j].x-cow[i].x));//否则更新面积(底『x的差』乘高『最高y值和最低y值的差』
  85. }
  86. }
  87. }
  88. cout << breed << endl << ans;
  89. }

你抄任你抄,过得了算我输

题解 P3117 【[USACO15JAN]牛的矩形Cow Rectangles】的更多相关文章

  1. 洛谷 P1522 牛的旅行 Cow Tours 题解

    P1522 牛的旅行 Cow Tours 题目描述 农民 John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧区通过任何路径都不 ...

  2. 洛谷 P1821 [USACO07FEB]银牛派对Silver Cow Party 题解

    P1821 [USACO07FEB]银牛派对Silver Cow Party 题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently ...

  3. Cow Rectangles

    Cow Rectangles 题目描述 The locations of Farmer John's N cows (1 <= N <= 500) are described by dis ...

  4. 洛谷P1522 牛的旅行 Cow Tours

    ---恢复内容开始--- P1522 牛的旅行 Cow Tours189通过502提交题目提供者该用户不存在标签 图论 USACO难度 提高+/省选-提交该题 讨论 题解 记录 最新讨论 输出格式题目 ...

  5. 「USACO13MAR」「LuoguP3080」 牛跑The Cow Run (区间dp

    题目描述 Farmer John has forgotten to repair a hole in the fence on his farm, and his N cows (1 <= N ...

  6. 洛谷P1522 [USACO2.4]牛的旅行 Cow Tours

    洛谷P1522 [USACO2.4]牛的旅行 Cow Tours 题意: 给出一些牧区的坐标,以及一个用邻接矩阵表示的牧区之间图.如果两个牧区之间有路存在那么这条路的长度就是两个牧区之间的欧几里得距离 ...

  7. [图论]牛的旅行 Cow Tours :Floyed-Warshall

    牛的旅行 Cow Tours 目录 牛的旅行 Cow Tours 题目描述 输入格式 输出格式 输入输出样例 输入 #1 输出 #1 解析 代码 题目描述 农民 John的农场里有很多牧区.有的路径连 ...

  8. bzoj1648 / P2853 [USACO06DEC]牛的野餐Cow Picnic

    P2853 [USACO06DEC]牛的野餐Cow Picnic 你愿意的话,可以写dj. 然鹅,对一个缺时间的退役选手来说,暴力模拟是一个不错的选择. 让每个奶牛都把图走一遍,显然那些被每个奶牛都走 ...

  9. bzoj1623 / P2909 [USACO08OPEN]牛的车Cow Cars

    P2909 [USACO08OPEN]牛的车Cow Cars 显然的贪心. 按速度从小到大排序.然后找车最少的车道,查询是否能填充进去. #include<iostream> #inclu ...

随机推荐

  1. “战疫”需求不再等-京东云与AI【应急资源信息发布平台】召集开发者共同支援

    截止北京时间 2020年2月5日19时00分,全国确诊新型冠状病毒肺炎24423例,疑似23260例. 新年伊始,一切都显得和往年有那么一点不一样.疫情牵动着每一个人的心脏,也有很多人早就放弃了假期投 ...

  2. nosql的介绍以及和关系型数据库的区别

    一直对非关系型数据库和关系型数据库的了解感觉不太深入,在网上收集了一些关于sql和nosql的区别和优缺点分享给大家. Nosql介绍 Nosql的全称是Not Only Sql,这个概念早起就有人提 ...

  3. oracle问题:char类型数据查询不到

    select distinct id,name from test_table b where b.ID='001' ; id为char字段类型,使用该语句查询不出数据. 解决方法:加trim().改 ...

  4. kafka 相关命令 偏移重置

    kafka官方文档 https://kafka.apache.org/documentation.html#quickstart kafka 安装文档 https://www.jianshu.com/ ...

  5. 【剑指Offer】面试题24. 反转链表

    题目 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3 ...

  6. Linux学习《第二章命令》本章小结

    经过这一章的学习,了解了常用的命令.这是学习Linux系统最最基础的工作,必须努力掌握,个人觉得,并不是这个章节学习结束之后,命令的学习就结束了,而是刚刚开始,今后在每个知识点学习过程中,都会 学习到 ...

  7. windows自带的颜色编辑器居中

    void xxx::SetOSDColor(CLabelUI * pLabel) { COLORREF color = RGB(*, *, *); CColorDialog cdlg(color, C ...

  8. linux shell的创建与启动

    1.创建shell脚本,输入linux命令: touch my.sh 2.编辑shell脚本,输入linux命令: vi my.sh 3.在shell脚本进行编辑:顺便记一次Jenkins的自动启动的 ...

  9. C语言预处理理论-宏定义2

    宏定义21.带参宏和带参函数的区别(1)宏定义是在预处理期间处理的,而函数是在编译期间处理的.这个区别带来的实质差异是:宏定义最终是在调用宏的地方把宏体原地展开,而函数是在调用函数处跳转到函数中去执行 ...

  10. eclipse的重要快捷键

    1.快速修正:ctrl + 1 2.单词补全:alt + / 3.查看轮廓:ctrl + o 4.打开eclipse中工作区的资源: ctrl + shift + r 它可以打开当前eclipse的工 ...