1382 - Distant Galaxy(技巧枚举+离散化)
2014-02-07 01:00
399 查看
You are observing a distant galaxy using a telescope above the Astronomy Tower, and you think that a rectangle drawn in that galaxy whose edges are parallel to coordinate axes and contain maximum star systems on
its edges has a great deal to do with the mysteries of universe. However you do not have the laptop with you, thus you have written the coordinates of all star systems down on a piece of paper and decide to work out the result later. Can you finish this task?
N
100) ,
the number of star systems on the telescope. N lines follow, each line consists of two integers: the X and Y coordinates of the K -th
planet system. The absolute value of any coordinate is no more than 109 , and you can assume that the planets are arbitrarily distributed in the universe.
N = 0 indicates the end of input file and should not be processed by your program.
题意:给定一些坐标的点,然后求出一个矩形上面点数最多
思路:由于坐标很大并且有负数,所以利用map离散化,然后每次枚举上边界和下边界,然后从左边界一直往右边界推,类似前缀求和思想维护一个最小值即可。原来没特判点全在一条直线的情况一直WA。。坑啊
代码:
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define INF 0x3f3f3f3f
using namespace std;
const int N = 105;
int n, x
, y
, xn, yn, g
, flag1, flag2;
vector<int> xp
, yp
;
map<int, int> xv, yv;
struct Point {
int x, y;
} p
;
bool cmp(Point a, Point b) {
return a.y < b.y;
}
void init() {
flag1 = flag2 = 0; int j;
xn = 1; yn = 1;
memset(g, 0, sizeof(g));
memset(xp, 0, sizeof(xp));
memset(yp, 0, sizeof(yp));
xv.clear(); yv.clear();
for (j = 0; j < n; j++) {
scanf("%d%d", &p[j].x, &p[j].y);
}
for (j = 1; j < n; j++) {
if (p[j].x != p[j - 1].x)
flag1 = 1;
if (p[j].y != p[j - 1].y)
flag2 = 1;
}
sort(p, p + n, cmp);
for (int i = 0; i < n; i++) {
int xx = p[i].x, yy = p[i].y;
if (!xv[xx]) {
xv[xx] = xn;
x[xn++] = xx;
}
if (!yv[yy]) {
yv[yy] = yn;
y[yn++] = yy;
}
g[xv[xx]][yv[yy]] = 1;
xp[xv[xx]].push_back(yy);
yp[yv[yy]].push_back(xx);
}
}
int solve() {
if (flag1 == 0 || flag2 == 0)
return n;
int ans = 0;
for (int i = 1; i < xn; i++) {
for (int j = i + 1; j < xn; j++) {
int Min = INF;
for (int k = 1; k < yn; k++) {
int s = 0, h = 0;
for (int x1 = 0; x1 < xp[i].size(); x1++) {
if (xp[i][x1] < y[k]) h++;
}
for (int x2 = 0; x2 < xp[j].size(); x2++) {
if (xp[j][x2] < y[k]) h++;
}
for (int y1 = 0; y1 < yp[k].size(); y1++) {
int up = max(x[i], x[j]);
int down = min(x[i], x[j]);
if (yp[k][y1] < up && yp[k][y1] > down)
s++;
}
ans = max(ans, h + s - Min + g[i][k] + g[j][k]);
Min = min(Min, h - s);
}
}
}
return ans;
}
int main() {
int cas = 0;
while (~scanf("%d", &n) && n) {
init();
printf("Case %d: %d\n", ++cas, solve());
}
return 0;
}
its edges has a great deal to do with the mysteries of universe. However you do not have the laptop with you, thus you have written the coordinates of all star systems down on a piece of paper and decide to work out the result later. Can you finish this task?
Input
There are multiple test cases in the input file. Each test case starts with one integer N , (1N
100) ,
the number of star systems on the telescope. N lines follow, each line consists of two integers: the X and Y coordinates of the K -th
planet system. The absolute value of any coordinate is no more than 109 , and you can assume that the planets are arbitrarily distributed in the universe.
N = 0 indicates the end of input file and should not be processed by your program.
Output
For each test case, output the maximum value you have found on a single line in the format as indicated in the sample output.Sample Input
10 2 3 9 2 7 4 3 4 5 7 1 5 10 4 10 6 11 4 4 6 0
Sample Output
Case 1: 7
题意:给定一些坐标的点,然后求出一个矩形上面点数最多
思路:由于坐标很大并且有负数,所以利用map离散化,然后每次枚举上边界和下边界,然后从左边界一直往右边界推,类似前缀求和思想维护一个最小值即可。原来没特判点全在一条直线的情况一直WA。。坑啊
代码:
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define INF 0x3f3f3f3f
using namespace std;
const int N = 105;
int n, x
, y
, xn, yn, g
, flag1, flag2;
vector<int> xp
, yp
;
map<int, int> xv, yv;
struct Point {
int x, y;
} p
;
bool cmp(Point a, Point b) {
return a.y < b.y;
}
void init() {
flag1 = flag2 = 0; int j;
xn = 1; yn = 1;
memset(g, 0, sizeof(g));
memset(xp, 0, sizeof(xp));
memset(yp, 0, sizeof(yp));
xv.clear(); yv.clear();
for (j = 0; j < n; j++) {
scanf("%d%d", &p[j].x, &p[j].y);
}
for (j = 1; j < n; j++) {
if (p[j].x != p[j - 1].x)
flag1 = 1;
if (p[j].y != p[j - 1].y)
flag2 = 1;
}
sort(p, p + n, cmp);
for (int i = 0; i < n; i++) {
int xx = p[i].x, yy = p[i].y;
if (!xv[xx]) {
xv[xx] = xn;
x[xn++] = xx;
}
if (!yv[yy]) {
yv[yy] = yn;
y[yn++] = yy;
}
g[xv[xx]][yv[yy]] = 1;
xp[xv[xx]].push_back(yy);
yp[yv[yy]].push_back(xx);
}
}
int solve() {
if (flag1 == 0 || flag2 == 0)
return n;
int ans = 0;
for (int i = 1; i < xn; i++) {
for (int j = i + 1; j < xn; j++) {
int Min = INF;
for (int k = 1; k < yn; k++) {
int s = 0, h = 0;
for (int x1 = 0; x1 < xp[i].size(); x1++) {
if (xp[i][x1] < y[k]) h++;
}
for (int x2 = 0; x2 < xp[j].size(); x2++) {
if (xp[j][x2] < y[k]) h++;
}
for (int y1 = 0; y1 < yp[k].size(); y1++) {
int up = max(x[i], x[j]);
int down = min(x[i], x[j]);
if (yp[k][y1] < up && yp[k][y1] > down)
s++;
}
ans = max(ans, h + s - Min + g[i][k] + g[j][k]);
Min = min(Min, h - s);
}
}
}
return ans;
}
int main() {
int cas = 0;
while (~scanf("%d", &n) && n) {
init();
printf("Case %d: %d\n", ++cas, solve());
}
return 0;
}
相关文章推荐
- Leetcode全排列问题
- android textview 显示一行,且超出自动截断,显示"..."
- 房价的同比和环比
- 20140207 - Java and Mac OS X Retina
- Android开发中网络编程与常见功能优化总结
- 浅谈Android中的几种网络请求方式
- 指针函数和函数指针有什么区别
- [转载]C# 中对html 标签过滤
- Mysql修改字符集之终极篇
- socket获取本机IP地址方法
- Eclipse + Java + WindowBuilder 可视化编程
- [转载]C# 判断字符是否中文还是英文
- 浅析iOS中的MVC
- 【C++基础】公有,私有和受保护的继承
- mongodb中索引对range查询和sort操作的影响
- 4G架构对移动网络的性能影响
- UVa 400 Unix 的 1s命令
- Myeclipse下修改Web根目录
- 剑指Offer - 九度1508 - 把字符串转换成整数
- Leetcode全匹配问题