poj 贪心题

这几天快要期末考试了, 也不能新学习什么算法,但是又不怎么想复习,就按着poj上的分类做一下贪心题

1 poj 1328

  这道题今年暑假的时候就看到了,一直拖到现在, 哎

  题意:海岸线的一边有岛屿, 现在要在海岸线上安装雷达,岛屿与雷达的距离在d之内可被雷达限号覆盖, 求最少雷大数

  思路:求出每个雷达的在海岸线上可被覆盖的区间,问题就转化为 区间选点问题

 

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef struct
{
   double l;
   double r;
}point;
point a[1010];
double x[1010], y[1010], d;
int n, ca = 1;
void work(int k)
{
   double m = sqrt(d*d - y[k]*y[k]);
   a[k].l = x[k] - m;
   a[k].r = x[k] + m;
}
bool cmp(point a, point b)
{
   return a.r < b.r;
}
int main()
{
	while(scanf("%d %lf", &n, &d), (n+d))
	  {  
	  	 bool flag = 0;
	  	 for(int  i=1; i<=n; i++)
	  	   {
	  	   	  scanf("%lf %lf", &x[i], &y[i]);
	  	   	  if(y[i] > d)
	  	   	  	flag = 1;
	  	   }
	  	 if(flag)
	  	   {
	  	   	  printf("Case %d: -1\n", ca++);
	  	   	  continue;
	  	   }
	  	 for(int i=1; i<=n; i++)
	  	 	work(i);
	  	 sort(a+1, a+n+1, cmp);
	  	 int ans = 1;
	  	 double k = a[1].r;
	  	 for(int i=2; i<=n; i++)
	  	 	if(a[i].l > k)
	  	 	  {
	  	 	  	 k = a[i].r;
	  	 	  	 ans++;
	  	 	  }
	  	 printf("Case %d: %d\n", ca++, ans);
	  }
	return 0;
}


2 poj  2109 

  分类上说这次贪心题, 不过我到没有贪心的感觉

   

#include <cstdio>
#include <cmath>
double n, p;
int main()
{
	while(scanf("%lf %lf", &n, &p) == 2)
	  {
         printf("%.0f\n", pow(p, 1/n));
 	  }
	return 0;
}

3 poj 2586

 题意:题意很难懂,后来实在看不懂看了这题的中文翻译, 这里就不阐述了

 思路:1 因为只有12个月, 因此课枚举12个月的盈亏情况,进行判断(但直接枚举超时了,还是稍稍优化了一下)

   

#include <cstdio>
#include <algorithm>
using namespace std;

int vis[15], a, b, ans;

void dfs(int cur)
{
    if(cur == 13)
      {
      	 int sum, flag = 1;
      	 for(int i=1; i<=8; i++)
      	   {
      	   	  sum = 0;
      	   	  for(int j=i; j<=i+4; j++)
      	   	    {
      	   	       if(vis[j])
      	   	       	 sum += a;
      	   	       else
      	   	       	 sum -= b;
      	   	    }
      	   	  if(sum >= 0)
      	   	   {
      	   	   	  flag = 0;
      	   	   	  break;
      	   	   }
      	   }
      	 if(flag)
      	   { 
      	   	 sum = 0;
      	   	 for(int i=1; i<=12; i++)
      	   	 	if(vis[i])
      	   	 	  sum += a;
      	   	 	else
      	   	 	 sum -= b;
      	   	 ans = max(ans, sum);
      	   }
      	return;
      }
    vis[cur] = 1;
    dfs(cur + 1);
    vis[cur] = 0;
    dfs(cur + 1);
}
int main()
{
	while(scanf("%d %d", &a, &b) == 2)
       {
       	  vis[1] = 1;
       	  ans = 0;
       	  dfs(2);
       	  if(ans)
       	  	printf("%d\n", ans);
       	  else
       	  	puts("Deficit");
       }
}
 

2 因为连续的五个月都是亏损的,故可枚举连续五个月中的盈的月数, 亏得月数为5-盈的月数

#include <cstdio>
int s, d, ans;
int main()
{
   while(scanf("%d %d", &s, &d) == 2)
   	 {
   	 	if(d > 4*s)          ans = 10*s - 2*d;
   	 	else if(2*d > 3*s)   ans = 8*s - 4*d;
   	 	else if(3*d > 2*s)   ans = 6*s - 6*d;
   	 	else if(4*d > s)     ans = 3*s - 9*d;
   	 	else ans = 0;
   	 	if(ans > 0)
   	 	  printf("%d\n", ans);
   	 	else
   	 	  puts("Deficit");
     }
   return 0;
}

4 poj 3069 

 没什么好说的, 水题

#include <cstdio>
#include <algorithm>
using namespace std;

int a[1010], r, n;

int binsearch(int k)
{
	int l = 1, r = n;
	int ans = 0;
	while(l <= r)
	  {
	  	 int m = (l + r) / 2;
	  	 if(a[m] <= k)
	  	   {
	  	   	  ans = m;
	  	   	  l = m+1;
	  	   }
	  	 else
	  	  r = m-1;
	  }
	return ans;
}
int main()
{
	while(scanf("%d %d", &r, &n) == 2)
	  {
	  	if(r==-1 && n==-1)
	  	   break;
	    for(int i=1; i<=n; i++)
	       scanf("%d", &a[i]);
	    sort(a+1, a+n+1);
	    int ans = 0;
	    for(int i=1; i<=n; i++)
	      {
	      	 int j = binsearch(a[i] + r);
	      	 ans++;
	      	 i = binsearch(a[j] + r);
	      }
	    printf("%d\n", ans);
	  }
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值