万恶之源

题意

给定若干个点的坐标,与范围R。每个点可以选择是否标记,标记后这个点的左右范围R内的所有点也会被标记,求为使所有点被标记,我们要主动标记多少个点。

思路

这题总感觉可以用搜索做,毕竟每个点的状态要么是1要么是0。但这是书上贪心的例题,那肯定得用贪心做啦。

贪心的原则是什么呢?

错解

首先我们的目标是尽可能少的标记,因此我们当然可以希望每次一次性标记的点越多越好,那么我们是不是可以遍历每个点,每次选择一次性标记数最多的点来标记呢?显然不行 我们可以看一下这个数据

1 9
1 2 2 3 3 3 4 4 5

显然在这种规则下程序会选择标记3,一口气标记了7个数字呢!然后呢,望不到彼此的1和5只能自己标记自己,因此最后我们主动标记了3个数。显然不是最优解。(其实这就是我的原始想法)

正解

我们可以从最左边开始考虑。在上述例子的条件下,我们肯定不会标记“1”,因为这样会浪费左边的范围,即标记“2”是优于标记“1”的。但是标记“3”就不是最优解了,为什么呢?因为标记“3”覆盖不到“1”,也就是留了个孤零零的元素没标记,这样子我们不得不单独的标记"1"。总而言之,标记“1”会浪费左边的空间,所以我们会试着选择标记“2”以及后面的元素,但是标记“3”不能照顾到”1“,带来了额外的成本,因此我们会选择标记2。所以我们希望被标记的点尽量靠右,不浪费左边的空间,但是也不能不覆盖最左边未标记的元素(即留空子)。

因此,贪心的原则应该是这样。

每次给最左边未标记的点的R范围内,最靠右的点标记。然后不断重复这一过程。

代码实现

书上的代码

int N, R;
int X[MAXN]; void solve(){
sort(X, X + N); int i = 0, ans = 0;
while(i < N){
int s = X[i++];//s是没有被覆盖的最左侧的位置
while(i < N && X[i] <= s + R) i++;
//一直向右前进,直到到达距离s的距离严格大于R的点(此处用的是小于等于号)
//相当于拓展p点的左侧 int p = X[i - 1];//p是新加上标记的点的位置,因为X[i]是接触不到s的
while (i < N && X[i] <= p + R) i++;
//一直向右前进,直到到达距离p的距离严格大于R的点
//相当于拓展p点的右侧 ans++;
}
printf("%d\n", ans);
}

我的代码

int r, n;
int troop[2000];//存储每只队伍的坐标 sort(troop, troop + n);
int tag = 0, ans = 0;////tag是没有被覆盖的最左侧的位置
troop[n] = 0x3f3f3f3f;//哨兵元素
for (int i = 0; i <= n; i++)
{
if (troop[i] - r > troop[tag]) {
ans++;
//标记点+1,没有明说,但标记的是i - 1
while (troop[i - 1] + r >= troop[tag]) tag++;
//更新标记点的右侧,也就是更新标记点的位置
}
//printf("%d---%d---%d\n", troop[i], troop[tag], ans);
}
printf("%d\n", ans);

比较一下

首先二者的思路是一致的。感觉区别在于书上的代码是一股气从左冲到右,而我的是一个一个检查,延迟标记(这也是为什么有一个哨兵的原因)

问题

我的问题主要在于一开始没有设置一个哨兵元素,然后我用很多if语句去判断各种情况来修补bug,但是修修补补终究不能AC。后来意识到标记不是即时的,才设置了一个哨兵元素,结果之前的if语句全部可以删掉,完美AC。可能一开始的方向就很重要吧。

历史提交

参考书籍:《挑战程序设计竞赛》

贪心-Saruman‘s Army POJ - 3069的更多相关文章

  1. Q - Saruman's Army POJ - 3069

    Saruman the White must lead his army along a straight path from Isengard to Helm's Deep. To keep tra ...

  2. Saruman's Army (POJ 3069)

    直线上有N个点.点i的位置是Xi.从这N个点中选择若干个,给它们加上标记.对每一个点,其距离为R以内的区域里必须又带有标记的点(自己本身带有标记的点,可以认为与其距离为0的地方有一个带有标记的点).在 ...

  3. POJ 3617 Best Cow Line ||POJ 3069 Saruman's Army贪心

    带来两题贪心算法的题. 1.给定长度为N的字符串S,要构造一个长度为N的字符串T.起初,T是一个空串,随后反复进行下面两个操作:1.从S的头部删除一个字符,加到T的尾部.2.从S的尾部删除一个字符,加 ...

  4. POJ 3069 Saruman's Army(贪心)

     Saruman's Army Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  5. poj 3069 Saruman's Army(贪心)

    Saruman's Army Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Tot ...

  6. poj 3069 Saruman's Army 贪心模拟

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18794   Accepted: 9222 D ...

  7. POJ 3069 Saruman's Army(萨鲁曼军)

    POJ 3069 Saruman's Army(萨鲁曼军) Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] Saruman ...

  8. poj 3069 Saruman's Army

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8477   Accepted: 4317 De ...

  9. POJ 3069:Saruman's Army

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13242   Accepted: 6636 D ...

随机推荐

  1. 真香!原来 CLI 开发可以这么简单

    CLI(命令行工具,Command Line Interface)大家都非常熟悉了,比如 create-react-app 等.我们今天介绍一个 CLI 工具的开发框架,可以帮助我们快速构建 CLI ...

  2. 边缘使用 K8s 门槛太高?OpenYurt 这个功能帮你快速搭建集群!

    OpenYurt作为阿里巴巴首个开源的边缘云原生项目,涉及到边缘计算和云原生两个领域.然而,许多边缘计算的开发者并不熟悉云原生相关的知识.为了降低 OpenYurt 的使用门槛,帮助更多地开发者快速上 ...

  3. 在树莓派用C#+Winform实现传感器监测

    最近学校里发了个任务,说要做一个科技节小发明,然后我就掏出我的树莓派准备大干一场. 调料 Raspberry Pi 3B+ 树莓派GPIO扩展板 3.5寸电容触摸屏(GPIO接口) 土壤湿度传感器(G ...

  4. 对javaEE Tutorial上hello2的源码分析详解

    首先: java EE 上的hello2项目是一个部署在glass fish上的开发源码的java web项目,在终端通过命令行使用maven进行打包成.war文件,最后部署到相关的glass fis ...

  5. PHP的变量赋值

    这个标题估计很多人会不屑一顾,变量赋值?excuse me?我们学开发的第一课就会了好不好.但是,就是这样基础的东西,反而会让很多人蒙圈,比如,值和引用的关系.今天,我们就来具体讲讲. 首先,定义变量 ...

  6. Git报错-refusing to merge unrelated histories

    执行git pull 时报错: 出现这个问题的最主要原因还是在于本地仓库和远程仓库实际上是独立的两个仓库.假如我之前是直接clone的方式在本地建立起远程github仓库的克隆本地仓库就不会有这问题了 ...

  7. Jmeter系列(12)- 上传接口压测

    step-1上传接口分析 上传接口源码分析:分析上传文件类型.有无大小限制.存放上传文件服务器 没有源码通过抓包工具,或者Chrome查看框架源代码 接口路径/uploadfile,接口请求POST, ...

  8. windows10 安装配置 jmeter 自动化接口测试 邮件报告

    1.安装依赖包:JDK(版本:jdk-7u17-windows-x64) 双击即可安装,注意:jdk不要安装中文路径下,jdk和jre安装在同一路径下 1.1:配置jdk环境变量 (1)JAVA_HO ...

  9. javascript base64 encode decode 支持中文

    * 字符编码 ** 一定要知道数据的字符编码 ** 使用utf-8字符编码存储数据 ** 使用utf-8字符编码输出数据 * Crypto.js 支持中文 Base64编码说明 Base64编码要求把 ...

  10. 自学 Java开发(Java后台开发|Java后端开发)的书籍推荐

    java编程思想java并发编程实战深入理解java虚拟机函数式编程思维tcp/ip详解鸟哥的linux私房菜spring mvc +mybatis开发从入门到精通spring技术内幕elastics ...