[POJ2456]Aggressive cows(贪心,二分查找)
2015-10-22 19:50
302 查看
题目链接:http://poj.org/problem?id=2456
二分+贪心
这是个求最小值最大的问题,我们二分从0到inf的数d,作为两头牛放置的距离不小于d,然后贪心判断。
首先要对x从小到大进行排序,接下来固定x[0]处必有一头牛,然后间距不小于d的时候,可以放置,一直放置,直到所有牛舍均被遍历O(n)。
如果牛被完全放置,那么返回true,并且向右确定边界,反之向左确定。
ac代码(32ms):
对于本题取ll还是rr的问题,如果拿不准可以每次更新ll,rr的时候同时选择是否更新ans,这样就不用纠结了。二分查找的限界也可以很无脑地记住。
二分+贪心
这是个求最小值最大的问题,我们二分从0到inf的数d,作为两头牛放置的距离不小于d,然后贪心判断。
首先要对x从小到大进行排序,接下来固定x[0]处必有一头牛,然后间距不小于d的时候,可以放置,一直放置,直到所有牛舍均被遍历O(n)。
如果牛被完全放置,那么返回true,并且向右确定边界,反之向左确定。
ac代码(32ms):
#include <cstdio> const int maxn = 100010; const int INF = 1 << 30; int n, m; int x[maxn]; int ll[maxn>>1], rr[maxn>>1]; inline bool scan_d(int &x) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){IsN=true;x=0;} else x=in-'0'; while(in=getchar(),in>='0'&&in<='9') { x*=10,x+=in-'0'; } if(IsN) x=-x; return true; } inline void printf_d(int a) { if(a > 9) { printf_d(a / 10); } putchar(a % 10 + '0'); } void merge(int *x, int p, int m, int q) { int n1 = m - p + 1; int n2 = q - m; int i = 0, j = 0; for(int ii = 0; ii < n1; ii++) ll[ii] = x[p+ii]; for(int ii = 0; ii < n2; ii++) rr[ii] = x[m+ii+1]; while(i < n1 && j < n2) { if(ll[i] <= rr[j]) x[p++] = ll[i++]; else x[p++] = rr[j++]; } while(i < n1) x[p++] = ll[i++]; while(j < n2) x[p++] = rr[j++]; } void mergesort(int *x, int p, int q) { if(p < q) { int m = (p + q) >> 1; mergesort(x, p, m); mergesort(x, m+1, q); merge(x, p, m, q); } } bool ok(int d) { int cow = 1; int tmp = x[0]; for(int i = 1; i < n; i++) { if(x[i] - tmp >= d) { cow++; tmp = x[i]; } } if(cow >= m) { return true; } return false; } int main() { // freopen("in", "r", stdin); while(scan_d(n) && scan_d(m)) { for(int i = 0; i < n; i++) { scan_d(x[i]); } mergesort(x, 0, n-1); int ll = 0, rr = INF; while(rr - ll > 1) { int mm = (ll + rr) >> 1; if(ok(mm)) { ll = mm; } else { rr = mm; } } printf_d(ll); putchar('\n'); } }
对于本题取ll还是rr的问题,如果拿不准可以每次更新ll,rr的时候同时选择是否更新ans,这样就不用纠结了。二分查找的限界也可以很无脑地记住。
const int maxn = 100010; int n, c, ans; int x[maxn]; bool ok(int d) { int cow = x[1]; int cnt = 1; for(int i = 2; i <= n; i++) { if(x[i] - cow >= d) { cnt++; cow = x[i]; } } return cnt >= c; } int main() { // freopen("in", "r", stdin); while(~scanf("%d %d", &n, &c)) { for(int i = 1; i <= n; i++) { scanf("%d", &x[i]); } int ll = 0; int rr = 0x7f7f7f7f; ans = 0x7f7f7f7f; sort(x+1,x+n+1); while(ll <= rr) { int mm = (ll + rr) >> 1; if(ok(mm)) { ll = mm + 1; ans = mm; } else rr = mm - 1; } printf("%d\n", ans); } return 0; }
相关文章推荐
- iOS开发拓展篇—音乐的播放
- iOS开发7-KVO(Key-Value Observer)键值观察
- Java并发之Lock的实现原理
- 盒子放球
- hihocoder1033交错和
- LeetCode题解——Ugly Number II
- IOS网络笔记--多线程编程2(线程安全--同步锁)
- Java设计模式2:简单工厂模式
- 关于微软必应词典客户端的案例分析
- 我现在大二,我找到我的方向了
- UVALive-3211 Now or later (2-SAT+二分)
- hihocoder1033交错和
- hdu 4782 Beautiful Soup(模拟)
- PM 周刊第 1 期 2015-10-19
- 学习java的前期知识
- Mac下Android的Eclipse开发环境的搭建
- spring+mybatis多数据源切换
- [linux] grep awk sort uniq学习
- T-SQL 学习之路之数据库完整性之域完整性
- UVA_11800_DetermineTheShape