这次是贪心(水笔贪心)专题。
先看1328,一道经典的导弹拦截(或者是打击?不懂背景)。
大意是说在一个坐标系中有一些点(或是导弹),你要在x轴上建一些东西,它们可以拦截半径为d的圆范围中的点。问最少修建的个数,不可能输出-1。
经典问题了哈,主要是把二维的转成一维。
对于每个要拦截的点以d为半径画一个圆。会与x轴有0/1/2个交点。如果没有交点直接退出-1即可,一个交点也可以看成两个交点重合。
这样我们就得到了一些线段,然后就是区间覆盖了。贪心走一遍即可。
两个端点的坐标勾股定理就好了:x±sqrt(d^2-y^2)
注意检查你的输出,我因为把Case 打成了case WA了N次(......)。
CODE
#include<cstdio> #include<math.h> #include<algorithm> using namespace std; const int N=1005; struct data { double x,y; }a[N]; int n,d,i,kinds,x,y; inline void read(int &x) { x=0; char ch=getchar(); int flag=1; while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=getchar(); } while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); x*=flag; } inline int comp(data a,data b) { return a.x<b.x; } int main() { for (kinds=1;;++kinds) { read(n); read(d); if (!n&&!d) break; bool flag=0; for (i=1;i<=n;++i) { read(x); read(y); if (y>d) flag=1; a[i].x=x-sqrt(1.0*d*d-1.0*y*y); a[i].y=x+sqrt(1.0*d*d-1.0*y*y); } if (flag) { printf("Case %d: -1 ",kinds); continue; } sort(a+1,a+n+1,comp); int ans=1; double last=a[1].y; for (i=2;i<=n;++i) if (a[i].x>last) ++ans,last=a[i].y; else if (a[i].y<last) last=a[i].y; printf("Case %d: %d ",kinds,ans); } return 0; }
2109:这是个智障题。
有一个等式k^n=p,现在给出n,p,让你求出k
这不是直接把p开n次方即可的事情吗?和贪心有何瓜葛?
double的精度在这题应该不会炸,开方也不用手写或高精检验,在精度范围内(k在1~1e9之间),所以用pow来做分数次幂就行了。
CODE
#include<cstdio> #include<cmath> using namespace std; double n,p; int main() { while (scanf("%lf%lf",&n,&p)!=EOF) printf("%.0lf ",pow(p,1/n)); return 0; }
2586:一个很简单的贪心题。
题目大意是一个二货公司每个月要么盈利s元,要么亏损d元,但是他们在一年中任意连续的5个月(1~5,2~6……)的盈亏和必须是负的。问你一年中可能盈利吗,可以就输出最大盈利值。
想一下就知道亏损的月份放在最后面最好(可以被多次利用)
所以假定他们12个月都盈利,在进行检查,如果和大于0就从后面开始修改。
CODE
#include<cstdio> #include<cstring> using namespace std; int sum,s,d,i; bool f[15]; inline void check(int a,int b) { for(;;) { int res=0; for (int i=a;i<=b;++i) if (f[i]) res+=s; else res-=d; if (res>=0) { int i=b; while (!f[i]&&i>a) --i; f[i]=0; } else break; } } int main() { while (scanf("%d%d",&s,&d)!=EOF) { memset(f,true,sizeof(f)); sum=0; for (i=1;i<=8;++i) check(i,i+4); for (i=1;i<=12;++i) if (f[i]) sum+=s; else sum-=d; if (sum<0) puts("Deficit"); else printf("%d ",sum); } return 0; }