博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVa 1616 - Caravan Robbers
阅读量:5221 次
发布时间:2019-06-14

本文共 1426 字,大约阅读时间需要 4 分钟。

链接:

 

题意:

输入n条线段,把每条线段变成原线段的一条子线段,使得改变之后所有线段等长且不相交(端点可以重合)。

输出最大长度(用分数表示)。

 

分析:

二分线段的长度,然后用贪心法检验可行性,最后把小数转换为分数。

这样做虽然能AC,但这也是测试数据的问题。原因是贪心的方法不完全正确。
无论是按线段的左端点排序,还是按右端点排序,都能找到出错的例子(见下面的测试数据)。
目前网上几乎所有关于这道题的题解都有这个问题,所以这道题还没解决。。。

 

代码:

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 struct TYPE { 7 int f, b; 8 bool operator < (const TYPE& that) const { 9 return b < that.b;10 }11 } a[100000+5];12 13 int main(){14 int n;15 while(~scanf("%d", &n)){16 for(int i = 0; i < n; i++) scanf("%d%d", &a[i].f, &a[i].b);17 sort(a, a + n);18 19 double L = 0, R = 1000000; //二分法20 while(R - L > 1e-9){21 int i;22 double M = L + (R - L) / 2, pos = 0;23 for(i = 0; i < n; i++){ //贪心法24 if(pos < a[i].f) pos = a[i].f;25 if(pos + M > a[i].b) break;26 pos += M;27 }28 if(i == n) L = M;29 else R = M;30 }31 32 int ac = 0, ad = 1; //小数转分数33 for(int d = 1; d <= n; d++){34 int c = round(L * d);35 if(fabs(1.0*ac/ad - L) > fabs(1.0*c/d - L)) ac = c, ad = d;36 }37 printf("%d/%d\n", ac, ad);38 }39 return 0;40 }

 

测试数据:

input1:

2

0 7
3 6

output1:

3/1

 

input2:

2

1 6
2 4

output2:

2/1

 

转载于:https://www.cnblogs.com/hkxy125/p/8543527.html

你可能感兴趣的文章
多态的理解
查看>>
刘波对大一的寄语
查看>>
【大数据学习】-Hadoop的版本(转)
查看>>
dev 数据加载等待提示框控件
查看>>
(ZT)杜君立:紧箍咒与纸枷锁
查看>>
运用starling开发的手游FlappyBird
查看>>
线程同步——用户模式下线程同步——Interlocked实现线程同步
查看>>
苹果开发者账号那些事儿(二)
查看>>
鲜贝7.3--mysql 下载小问题
查看>>
[luogu2576 SCOI2010] 幸运数字 (容斥原理)
查看>>
修炼内功--动态代理
查看>>
ASP.NET打包生成zip压缩文件
查看>>
机器学习算法(5):卷积神经网络原理及其keras实现
查看>>
团队冲刺计划第十天
查看>>
linux下gcc编译多个源文件、gdb的使用方法(转)
查看>>
python学习之路---编程风格规范
查看>>
git reflog查看所有操作记录
查看>>
2016百度编程题:裁减网格纸
查看>>
sqlserver 小计合计总计
查看>>
git pull和git fetch的区别
查看>>