【uva 1312】Cricket Field(算法效率--技巧枚举)

题意:一个 L*R 的网格里有 N 棵树,要求找一个最大空正方形并输出其左下角坐标和长。(1≤L,R≤10000, 0≤N≤100)

解法:枚举空正方形也就是枚举空矩阵,先要固定一个边,才好继续操作。(P.S.许多类型的题都是这样:先固定一个变量,再比较另外的变量。这种思想在贪心、DP等都常出现,一定要掌握!)所以这题就是先枚举一条边的范围(横坐标),再枚举排序后的点,根据当前枚举的点和之前纵坐标最大的点的纵坐标得到这条边的长度,再比较、更新答案。

P.S.我这题打了2个小时!??º·(? ?????????? )?º·? 一定要注意细节啊!还有......我的行列是与题目相反着存的。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<iostream>
 6 using namespace std;
 7
 8 const int N=110,D=10010;
 9 int n,l,r,m;
10 struct node{int x,y;}a[N];
11 int b[N];
12
13 int mmin(int x,int y) {return x<y?x:y;}
14 int mmax(int x,int y) {return x>y?x:y;}
15 bool cmp(node x,node y)
16 {
17     if (x.y!=y.y) return x.y<y.y;
18     return x.x<y.x;
19 }
20 int main()
21 {
22     int T;
23     scanf("%d",&T);
24     while (T--)
25     {
26       scanf("%d%d%d",&n,&r,&l);
27       m=1; b[1]=0;
28       for (int i=1;i<=n;i++)
29       {
30         scanf("%d%d",&a[i].y,&a[i].x);//
31         b[++m]=a[i].x;
32       }
33       b[++m]=l;//没有+1...
34       sort(a+1,a+1+n,cmp);
35       sort(b+1,b+1+m);
36       int p=1;
37       for (int i=2;i<=m;i++)
38         if (b[i]!=b[i-1]) b[++p]=b[i];
39       m=p;
40
41       int tx=0,ty=0,ans=0;
42       for (int i=1;i<=m;i++)
43        for (int j=i+1;j<=m;j++)
44        {
45          int mxy=0,tmp;
46          for (int k=1;k<=n;k++)
47          {
48             if (a[k].x<b[i]||a[k].x>b[j]) continue;//别轻易break
49             tmp=mmin(b[j]-b[i],a[k].y-mxy);
50             if (tmp>ans) {ans=tmp; tx=b[i]; ty=mxy;}
51             if (a[k].x!=b[i] && a[k].x!=b[j]) mxy=a[k].y;
52          }
53          tmp=mmin(b[j]-b[i],r-mxy);//边界勿漏
54          if (tmp>ans) {ans=tmp; tx=b[i]; ty=mxy;}
55        }
56       printf("%d %d %d\n",ty,tx,ans);
57       if (T) printf("\n");
58     }
59     return 0;
60 }
时间: 2024-11-05 18:40:52

【uva 1312】Cricket Field(算法效率--技巧枚举)的相关文章

UVa 1312 Cricket Field (枚举+离散化)

题意:在w*h的图上有n个点,要求找出一个正方形面积最大,且没有点落在该正方形内部. 析:枚举所有的y坐标,去查找最大矩形,不断更新. 代码如下: #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <

UVA - 1312 Cricket Field 构造

题目大意:在一个W * H的网格中有n棵树,要求你在这个网格中找出最大个的一个正方形,这个正方形内部不能有树,边上可以有树 解题思路:刚开始以为要暴力枚举每一个点,结果发现错了,其实这题就像UVA - 1382 Distant Galaxy这题一样,只不过这个是要找正方形,找正方形和找矩形类似,只需要取矩形的最小边就可以了 #include<cstdio> #include<algorithm> using namespace std; #define maxn 110 struc

UVA 1312 Cricket Field

题意: 在w*h的坐标上给n个点, 然后求一个最大的矩形,使得这个矩形内(不包括边界)没有点,注意边界上是可以有点的. 分析: 把坐标离散化.通过两重循环求矩形的高,然后枚举,看是否能找到对应的矩形. 代码: #include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int

1312 - Cricket Field

该题的网格大小非常大,看似需要离散化,但是实际上是不需要的 .  因为我们可以发现,既然要求正方形里没有树,我们不妨直接枚举树就可以了 . 所以我们将纵坐标单独拿出来从小到大排序,二重循环就可以枚举出矩形上下界,然后关键是横坐标的枚举. 同样,我们将横坐标排序,然后判断对应的纵坐标是否在上下界范围内,通过观察,如果不在,那么这个点将不在当前枚举的矩形中,所以直接跳过就可以了,这样的话,我们只需要一个变量来动态维护左边界就可以了 . 细节 参见代码: #include<bits/stdc++.h>

【uva 1615】Highway(算法效率--贪心 区间选点问题)

题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到一个个区间,这样就是选最小的点覆盖所有的区间的问题了.我之前的一篇博文有较详细的解释:关于贪心算法的经典问题(算法效率 or 动态规划).代码实现我先空着.挖坑~

UVA 10458 - Cricket Ranking(容斥原理)

UVA 10458 - Cricket Ranking 题目链接 题意:给定k个区间,要求用这些数字范围去组合成n,问有几种组合方式 思路:容斥原理,容斥是这样做:已知n个组成s,不限值个数的话,用隔板法求出情况为C(s + n - 1, n - 1),但是这部分包含了超过了,那么就利用二进制枚举出哪些是超过的,实现把s减去f(i) + 1这样就保证这个位置是超过的,减去这部分后,有多减的在加回来,这就满足了容斥原理的公式,个数为奇数的时候减去,偶数的时候加回 代码: #include <cst

《数据结构与算法分析:C语言描述》复习——第十章“算法设计技巧”——Alpha-Beta剪枝

2014.07.08 22:43 简介: “搜索”与“剪枝”几乎是如影随形的.此处的“搜索”指的是带有回溯算法的深度优先搜索. 在之前的“Minimax策略”中我们给出了一个三连棋的程序,运行后你就知道计算一步棋要花多少时间. 为了计算最优的一步棋,我们可能需要递归9万多次.如果毫无疑问这种阶乘式的穷举过程必须通过剪枝来加速. 本篇介绍一种用于Minimax策略的剪枝思路——α-β剪枝. 剪枝的英语是pruning,所以不要想当然说成trimming. 图示: 在上一篇讲解Minimax策略的博

Codeforces Gym 100002 C &quot;Cricket Field&quot; 暴力

"Cricket Field" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100002 Description Once upon a time there was a greedy King who ordered his chief Architect to build a field for royal cricket inside his park. The King was so

基础算法之二——枚举法

基础算法之二--枚举法"赛利的硬币" 题目描述 赛利有 12枚银币.其中有 11枚真币和1枚假币.假币看起来和真币没有区别,但是重量不同.但赛利不知道假币比真币轻还是重.于是他向朋友借了一架天平.朋友希望赛利称三次就能找出假币并且确定假币是轻是重.例如:如果赛利用天平称两枚硬币,发现天平平衡,说明两枚都是真的.如果赛利用一枚真币与另一枚银币比较,发现它比真币轻或重,说明它是假币.经过精心安排每次的称量,赛利保证在称三次后确定假币. 输入数据 输入有三行,每行表示一次称量的结果.赛利事先