zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 075 D

    https://beta.atcoder.jp/contests/abc075/tasks/abc075_d

    题意:

    给出坐标平面上n个点的坐标,要求找到一个面积最小的矩形使得这个矩形的边界加上内部的点的数量大于等于k。

    思路:

    由于坐标过大,所以离散化。

    离散化之后用前缀和,但是Orz求前缀和的时候写错了。

    枚举左下角和右上角的坐标,分别为(i,j)和(s,e)。

    那么点的数量为sum[s][e] - sum[s][j-1] - sum[i-1][q] + sum[i-1][j-1],切记,切记,画图画图。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <map>
     5 using namespace std;
     6 
     7 struct node
     8 {
     9     int x,y;
    10 } a[55];
    11 
    12 map<int,int> mpx,mpy;
    13 map<int,int> invx,invy;
    14 
    15 int sum[55][55];
    16 int b[55][55];
    17 
    18 bool cmp1(node aa,node bb)
    19 {
    20     return aa.x < bb.x;
    21 }
    22 
    23 bool cmp2(node aa,node bb)
    24 {
    25     return aa.y < bb.y;
    26 }
    27 
    28 int main()
    29 {
    30     int n,k;
    31 
    32     scanf("%d%d",&n,&k);
    33 
    34     for (int i = 1;i <= n;i++)
    35     {
    36         scanf("%d%d",&a[i].x,&a[i].y);
    37     }
    38 
    39     long long ans;
    40 
    41     sort(a+1,a+n+1,cmp1);
    42 
    43     for (int i = 1;i <= n;i++)
    44     {
    45         invx[i] = a[i].x;
    46         mpx[a[i].x] = i;
    47     }
    48 
    49     long long dx = a[n].x - a[1].x;
    50 
    51     sort(a+1,a+n+1,cmp2);
    52 
    53     for (int i = 1;i <= n;i++)
    54     {
    55         invy[i] = a[i].y;
    56         mpy[a[i].y] = i;
    57     }
    58 
    59     long long dy = a[n].y - a[1].y;
    60 
    61     ans = dx * dy;
    62 
    63     for (int i = 1;i <= n;i++)
    64     {
    65         int x = a[i].x,y = a[i].y;
    66 
    67         b[mpx[x]][mpy[y]] = 1;
    68     }
    69 
    70     for (int i = 1;i <= n;i++)
    71         for (int j = 1;j <= n;j++)
    72         {
    73             sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + b[i][j];
    74         }
    75 
    76     for (int i = 1;i <= n;i++)
    77         for (int j = 1;j <= n;j++)
    78         {
    79             for (int s = i;s <= n;s++)
    80                 for (int q = j;q <= n;q++)
    81                 {
    82                     if (sum[s][q] - sum[s][j-1] - sum[i-1][q] + sum[i-1][j-1] >= k)
    83                     {
    84                         long long dx = invx[s] - invx[i];
    85                         long long dy = invy[q] - invy[j];
    86 
    87                         long long tmp = abs(dx) * abs(dy);
    88 
    89                         ans = min(ans,tmp);
    90                     }
    91                 }
    92         }
    93 
    94     printf("%lld
    ",ans);
    95 
    96     return 0;
    97 }
  • 相关阅读:
    二分查找
    泛型 学习
    一个时间转换的功能的类
    TCP/IP、Http、Socket的区别
    值得学习的
    popupwindow使背景变暗
    设计模式最好的学习网站
    观察者模式
    数据报的使用
    网络编程server
  • 原文地址:https://www.cnblogs.com/kickit/p/7669044.html
Copyright © 2011-2022 走看看