POJ初级分类 贪心专题 poj1328 POJ2109 POJ 2586
Posted huatian5
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ初级分类 贪心专题 poj1328 POJ2109 POJ 2586相关的知识,希望对你有一定的参考价值。
题目1328
代码及解释:
/*
POJ1328
Radar Installation
题目大意:有一条海岸线,一边是海岸,一边是大海;海中有一些小岛,我们要建造一些雷达,从而可以覆盖所有小岛,要求雷达的最小数目。
思路:贪心法的套路。每次计算对小岛做一个半径为d的圆,如果与x轴有交点的话(如果有任何无交点的情况,输出-1),那么就用勾股定理计算出来算出来每个岛与x轴交点
的两个坐标,分别是 left 和 right ,如果A岛得到的left在B岛的right左面,那么A岛与B岛肯定可以共圆,so不需要建筑一个雷达,反之,继续建造。
只想说,贪心好强,但是不好想啊。。。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct Point
int x;
int y;
p[1005];
struct position
double left;
double right;
pos[1005],temp;
bool cmp(position a,position b)
return a.right<b.right;
int n,d;
//用勾股定理计算出每个圆与x轴交点的左右横坐标
void Cx()
for(int i=0;i<n;i++)
double s = sqrt(1.0*d*d-1.0*p[i].y*p[i].y);
pos[i].left = (double)p[i].x - s;
pos[i].right = (double)p[i].x + s;
int main()
int t=0;
while(~scanf("%d%d",&n,&d)&&(n||d))
int flag=0;//判断是否有不能覆盖的情况
for(int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
if(p[i].y>d)
flag=1;
printf("Case %d: ",++t);
if(flag)//-1的情况
cout<<-1<<endl;
continue;
Cx();
sort(pos,pos+n,cmp);
int sum=1;
temp=pos[0];
for(int i=1;i<n;i++)
if(pos[i].left>temp.right)//如果A岛得到的left不在B岛的right左面
sum++;
temp=pos[i];
else if(pos[i].right<temp.right)//圆被包含
temp=pos[i];
printf("%d\\n",sum);
return 0;
题目:POJ2109
/*float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;
double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。*/
所谓的贪心竟然是卡double精度,有的人想到log()就错了,因为log(k,p)是不能直接计算的,所以要化为log(p)/log(k),然后就是多次运算带来的误差不能承受了。
(看了下知乎,了解了范围带来的影响,没有范围这种bug方法不能过的)主要是1<=k<=109,精度限制就没问题了。
当然,“正规”方法是高精度。
代码及解释:
/*float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;
double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。*/
#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
double n,p;
while(~scanf("%lf%lf",&n,&p))
cout<<pow(p,1.0/n)<<endl;
return 0;
高精度:
理解题意一直都是硬伤,英语进步缓慢啊,好好反思一下,是自己太烂太贪玩了啊
题目大意及AC代码:
/*
poj2586
Y2K Accounting Bug
题目大意(好难懂):这个公司出事了,进病毒了,每个月可能盈利可能亏损,但是公司竟然不记得了,公司(((每个连续的五个月)))报表一次,一共就八次喽,
1~5,2~6……
只记得每次报表都亏了,所以,让计算这个公司还有可能盈利吗,如果可能,最多能盈利多少
思路:在保证每个五个月都亏损,但是亏损尽量少,就可以求得最大收益了。
这就要求任意连续的五个月中至少有一个是亏损的,并且尽量使亏损减少
情况不多,就是枚举啦,然后根据s和d的范围确定最后的盈利与否
1. ssss d ssss d ss 10个盈利月数,2个亏损月数,任意五个月1个亏损月
2. sss dd sss dd ss 8个盈利月数,8个亏损月数,任意五个月2个亏损月
3. ss ddd ss ddd ss 6个盈利月数,6个亏损月数,任意五个月3个亏损月
4. s dddd s dddd sd 3个盈利月数,9个亏损月数,任意五个月4个亏损月
5. dddddddddddd 0个盈利月数,12个亏损月数,任意五个月0个亏损月
*/
#include<iostream>
#include<cstdio>
using namespace std;
int main()
int s,d;
int ss,dd;
while(~scanf("%d%d",&s,&d))
if(d>4*s)
ss=10;
dd=2;
else if(2*d>3*s)
ss=8;
dd=4;
else if(3*d>2*s)
ss=6;
dd=6;
else if(4*d>s)
ss=3;
dd=9;
else
ss=0;
dd=12;
if(ss*s-dd*d>=0)
printf("%d\\n",ss*s-dd*d);
else
printf("Deficit\\n");
return 0;
贪心的方法应该类似吧,感觉这也是一种贪心的思想
以上是关于POJ初级分类 贪心专题 poj1328 POJ2109 POJ 2586的主要内容,如果未能解决你的问题,请参考以下文章