题意:有N间牛舍,有M头牛,要合理的安排一个最大距离,使得这些牛不能够相互攻击到。
思路:
这题也是设计到了最大化问题,即奶牛之间两两距离最大,可以考虑二分查找的思路
同样的这题也要考虑一下贪心策略,要把奶牛先安置在比较靠前的牛舍中
首先第0个宿舍肯定要入住奶牛的,所以就要考虑从1到M-1个奶牛的宿舍问题了
这题的判断是否成立的条件也是关键
bool is_ok(int x) { int cur; int last=0; for(int i=1;i<M;i++)//这儿有个小问题就是为什么不是从0开始 //因为第0个房子一定要装一头奶牛的,所以要从第二头奶牛开始考虑 { cur=last+1; while(cur<N && (dom[cur]-dom[last])<x)//当前的宿舍要小于N,并且这个宿舍之间的距离还要小于x { cur++; } if(cur==N) return false;//到达了最后一个宿舍说明没有成立的就返回FALSE last=cur;//要是不是那么就要把last这个中间变量重新赋值 } return true; }
然后二分查找可以设置一个精度值,因为都是int类型的变量,完全可以用1来作为精度
二分查找很好实现所以下面直接贴出完整的代码吧
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int N,M; int dom[100002]; const int INF=1e9; bool is_ok(int x) { int cur; int last=0; for(int i=1;i<M;i++)//这儿有个小问题就是为什么不是从0开始 //因为第0个房子一定要装一头奶牛的,所以要从第二头奶牛开始考虑 { cur=last+1; while(cur<N && (dom[cur]-dom[last])<x)//当前的宿舍要小于N,并且这个宿舍之间的距离还要小于x { cur++; } if(cur==N) return false;//到达了最后一个宿舍说明没有成立的就返回FALSE last=cur;//要是不是那么就要把last这个中间变量重新赋值 } return true; } void solve() { sort(dom,dom+N);//本题要用到贪心算法,要对宿舍先进行排序 int low=0; int high=INF; while(high-low>1)//这儿是利用精确度只要大于1 就可以满足了精确度 { int mid=(low+high)/2; if(is_ok(mid)) low=mid; else high=mid; } printf("%d ",low); } int main() { while(cin>>N>>M) { for(int i=0;i<N;i++) cin>>dom[i]; solve(); } return 0; }