题目

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1696

题意

平面上有n个整数点,找一个矩形,使得边界上包含尽量多的点。

思路

如刘书

首先可以按照x对所有点排序,然后枚举矩形左右边界

确定左右边界之后,接下来就可以枚举下边界,直接求最优上边界。

当左右下边界确定后,就能知道图中粉色部分上有多少个点,但这样离求出带上边界的矩形上有多少个点还差一点。如图,假如上边界是淡绿色边,那么还需要去掉紫色的两段左右边界上不属于矩形的前缀,再加上上边界上橙色的那段。

如何求最优上边界呢?明显,最优上边界和下边界无关,只与自身的x和左右边界有关。所以我们可以直接记录目前为止的最优上边界-也就是记录橙色部分的点减去紫色前缀中点后还剩下点的最大值-该最大值对应的就是最优上边界。

假设左边界对应ymin,右边界ymax,那么对于一条横边x = x0,设cntcorner为左右边界与横边相交位置上存在的点,cnt为左右边界夹住(不包括相交位置)的点。prefix为cntcorner累计值,也即y=ymin或ymax,x <= x0的点数,那么粉色的部分=prefix + cnt,

设另外一条横边x = x1, x1 < x0为上边界,对应cnt', cntcorner'和prefix‘,那么此时矩形上的点就是prefix + cnt + cnt' - prefix' - cntcorner'

cnt' - prefix' - cntcorner'的最大值对应最优上边界。

代码

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#define LOCAL_DEBUG
using namespace std;
const int MAXN = 1e2 + ;
typedef pair<int, int> MyPair;
MyPair pt[MAXN];
int y[MAXN];
int n; int check(int ymin, int ymax) {
int reserve = , ans = ;
for (int i = , ygap = ; i < n;) {
if (pt[i].second < ymin || pt[i].second > ymax) {
i++; continue;
}
int x = pt[i].first;
int cnt = , cntcorner = ;
for (int j = i; j < n && pt[j].first == x && pt[j].second <= ymax && pt[j].second >= ymin; i++, j++) {
if (pt[j].second == ymin || pt[j].second == ymax)cntcorner++;
else cnt++;
}
ans = max(ans, reserve + cnt + cntcorner + ygap);
reserve = max(reserve, cnt - ygap);
ygap += cntcorner;
}
return ans;
} int main() {
#ifdef LOCAL_DEBUG
freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
//freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
#endif // LOCAL_DEBUG
//int T;
// scanf("%d", &T);
for (int ti = ;scanf("%d", &n) == && n; ti++) {
for (int i = ; i < n; i++) {
scanf("%d%d", &pt[i].first, &pt[i].second);
y[i] = pt[i].second;
}
sort(pt, pt + n);
sort(y, y + n);
int ynum = ;
for (int i = ; i < n; i++) {
if (i && y[i] == y[i - ]) {
continue;
}
else {
y[ynum++] = y[i];
}
}
int ans = -;
if (ynum <= )ans = n;
else {
for (int i = ; i < ynum; i++) {
for (int j = i + ; j < ynum; j++) {
ans = max(ans, check(y[i], y[j]));
}
}
}
printf("Case %d: %d\n", ti, ans);
} return ;
}

UVa LA 3695 - Distant Galaxy 前缀和,状态拆分,动态规划 难度: 2的更多相关文章

  1. LA 3695 Distant Galaxy

    给出n个点的坐标(坐标均为正数),求最多有多少点能同在一个矩形的边界上. 题解里是构造了这样的几个数组,图中表示的很明白了. 首先枚举两条水平线,然后left[i]表示竖线i左边位于水平线上的点,on ...

  2. 【UVALive】3695 Distant Galaxy(......)

    题目 传送门:QWQ 分析 好喵啊~~~~ 不会做 正解看蓝书P53吧 代码 #include <cstdio> #include <algorithm> using name ...

  3. UVALive - 3695 Distant Galaxy

    InputThere are multiple test cases in the input file. Each test case starts with one integer N, (1 ≤ ...

  4. UVaLive 3695 Distant Galaxy (扫描线)

    题意:给平面上的 n 个点,找出一个矩形,使得边界上包含尽量多的点. 析:如果暴力那么就是枚举上下边界,左右边界,还得统计个数,时间复杂度太高,所以我们考虑用扫描线来做,枚举上下边界, 然后用其他方法 ...

  5. UVA LA 7146 2014上海亚洲赛(贪心)

    option=com_onlinejudge&Itemid=8&page=show_problem&category=648&problem=5158&mosm ...

  6. hdu Distant Galaxy(遥远的银河)

    Distant Galaxy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  7. LA3695 Distant Galaxy

    Distant Galaxy https://vjudge.net/problem/UVALive-3695 You are observing a distant galaxy using a te ...

  8. BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划

    BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...

  9. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

随机推荐

  1. leecode第四十三题(字符串相乘)

    class Solution { public: string multiply(string num1, string num2) { ";//特殊情况 ] == ] == ') retu ...

  2. 《剑指offer》第五十三题(数组中数值和下标相等的元素)

    // 面试题53(三):数组中数值和下标相等的元素 // 题目:假设一个单调递增的数组里的每个元素都是整数并且是唯一的.请编程实 // 现一个函数找出数组中任意一个数值等于其下标的元素.例如,在数组{ ...

  3. 分析:java.lang.OutOfMemoryError: Java heap space

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Hashta ...

  4. Codeforces 960D - Full Binary Tree Queries

    960D - Full Binary Tree Queries 思路: 用move1[i]记录第i层第1种操作移动的个数(对这一层的个数取模) 用move2[i]记录第i层第2种操作移动的个数(对这一 ...

  5. 关于ascii码的一些内容

    1.通过C#程序输出tab(制表符)内容. 1.1常用方式我们可以是 //测试输出\t到文件 File.WriteAllText("test.txt", "a\tb\tc ...

  6. Vue音乐项目笔记(三)

    1. 音乐播放前进后退的实现   https://blog.csdn.net/weixin_40814356/article/details/80379606 2. 音乐进度条实现(单独一个组件) h ...

  7. CF903G Yet Another Maxflow Problem

    考虑最大流=最小割 不妨把a到a的边称为a类边,b到b的称为b类边,a到b的称为c类边. 显然,答案一定是由最多1条a和最多一条b以及一些c组成的. 只有a是会变的,也就是说每个a对应了唯一的最优的b ...

  8. 网络管理命令ping和arping

    ping ping        向目标主机发送icmp请求包 常用来测试当前主机与目标主机网络连接状况 常见选项 -c              设置发包的个数 -s               设 ...

  9. 巧用JSON

    在开发的过程中,对json的接触基本是前端页面搭建完成后,对后台数据的请求.如果接口尚未提供,一般情况下会先按规定的要求写好需要的json模拟出请求的后台数据.json的格式有很多种,关注的主体是da ...

  10. bzoj3876: [Ahoi2014&Jsoi2014]支线剧情

    题意:给一幅图,从1开始,每条边有边权最少走一遍,可以在任意点退出,问最小花费 题解:上下界费用流,每个边都流一遍,然后为了保证流量平衡,新建源点汇点,跑费用流把流量平衡 /************* ...