poj3258
来源:互联网 发布:ubuntu 安装apache 编辑:程序博客网 时间:2024/05/01 05:24
题目较难。题目大致题意为母牛要过河,起始位置为0,终止位置为L,中间有n个石头,在可以移开最多m(0<=m<=n)块石头的情况下,求最大的(石块间的最小距离)。
题目与poj3273相似。可对照poj3273结题报告分析,分析如下:
选定一个数x,按照任意石头之间距离不小于(即>=)x的原则分组(结合贪心算法分组),求得最小石头移开数。
1)若最小石头移开数大于m,则说明该数大了,要减小。
2)若最小石头移开数小于等于m,则说明满足题意。那么我们就求以求出这些数中最大的x
而x的范围为0——L,且f(x)单调递增,f(x)表示对于给定的最小间隔,最小石头移开数。故可以利用二分查找法求得满足f(x)<=m的最大x。
下面是程序: 328K+94MS
#include <stdio.h>#include <stdlib.h>#include <algorithm>#define Max 50010 // 最大个数using namespace std;int record[Max]; // 记录石头的位置int L,n,m;int main(){scanf("%d%d%d",&L,&n,&m);record[0]=0; // 起始位置为0record[n+1]=L; // 结束位置为Lfor(int i=1;i<=n;i++) // 输入石头位置scanf("%d",&record[i]);sort(record+1,record+1+n); //对石头位置进行升序排序int left=0,right=L,mid; //0<=x<=L,二分法求解满足最少石头移开数f(x)<=m的最大x值while(left<=right){mid=(left+right)>>1;int ans=0,Sum,Count=0;
// ans,Sum,Count依次表示从哪个石头开始检查、第i个石头与第ans个石头之间的距离、移开石头个数
for(int i=1;i<=n+1;i++){ // 贪心法求解对于给定的x,按照上述组合方式所需移开的最小石头个数,注意这里i循环到n+1,而不是n(想想为什么)Sum=record[i]-record[ans];if(Sum<mid) // 若距离小于mid,则说明要移开第i个石头Count++; // 移开石头数增加else{ // 否则 从 第 i 个石头开始重新检验ans=i; }}if(Count>m) //若最小移开石头数大于m,则说明该数大了,要减小right=mid-1;elseleft=mid+1;//否则求出这些数中的最大值}printf("%d\n",right); //输出最大值return 0;}
0 0
- poj3258
- poj3258
- poj3258
- poj3258
- poj3258
- poj3258
- POJ3258
- poj3258
- poj3258
- poj3258 二分
- POJ3258 二分
- POJ3258 二分
- POJ3258【二分】
- poj3258 二分
- poj3258解题报告
- POJ3258:River Hopscotch
- POJ3258-River Hopscotch
- poj3273+poj3258 二分易错点
- 两种滚动跑马灯效果-从当前位置开始
- 美素数
- java架构师喜欢问的问题
- Mac下配置tomcat
- 另外一篇字符编码的好文章
- poj3258
- 个人各国法国恢复规划
- JAVA 解压文件
- LQX的作业
- redis读写分离下的高可用设计与实现(上)
- 不小心把手机里的照片删了怎么恢复
- 一键合成APK
- 拼装html字符串的最快方法
- ConfigurationSection类使用心得