貪心::poj1328 radar installation && poj2109 Power of Cryptography && poj2586 Y2K Accounting Bug

貪心,就是步步為贏。

這是ACM知識表里基礎算法中的貪心部分,屬於水題範疇。

1. poj1328 radar installation

題目:照抄了。

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.
We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

分析:根據d計算出每個島在x軸上的取值範圍(用區間表示)。按左端點對區間從小到大進行排序。先令第一個雷達在第一個區間的右端點,(畫個圖就清楚了),然後順序掃描剩下的各個區間,如果下一個區間的左端點大於當前雷達位置,則要增加雷達在下一個區間的右端點,如果雷達位置在下一個區間[p[i].l,p[i].r]裡面,則令雷達位置右移到p[i].r,此時不用增加雷達而能覆蓋下一個島!這是Greedy的算法。

貌似所有的math.h中的算法都是double的~~

時間複雜度為O(nlgn)為sort的快排!

 

#include "stdafx.h"      // 280K 16MS 
#include <math.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef struct{
     double l, r;
}interval; // 区间
bool cmp(interval a,interval b){return a.l<=b.l;}
int _tmain(int argc, _TCHAR* argv[])
{ 
     int n, d, i, x, y, cnt = 1;
     double pre; 
     interval p[1000]; 
     while(1){ 
         cin>>n>>d; 
         if(n == 0 && d == 0) break; 
         bool no = 0; 
         for(i = 0; i < n; i++){  
              cin>>x>>y; 
              if(d >= y && !no){
                   p[i].l = double(x) - sqrt(double(d * d - y * y)); 
                   p[i].r = double(x) + sqrt(double(d * d - y * y));
              }  
              else
                   no = 1;       //不知為何,在這裡break的話就不行!
           } 
         if(no){  
              cout<<"Case "<<cnt++<<": -1"<<endl; 
              continue; 
         } 
         sort(p,p+n,cmp);
         int ans = 1; 
         pre = p[0].r; 
         for(i = 1; i < n; i++){  
              if(p[i].l > pre){   
                   ans++;   
                   pre = p[i].r;
              }  
              else if(p[i].r <= pre) 
                       pre = p[i].r; 
         }  
         cout<<"Case "<<cnt++<<": "<<ans<<endl;;
     } 
     return 0;
}

2.  poj2109 Power of Cryptography

題目:已知整數n和p,求整數k使得k..^n=p成立。

分析:雖說是貪心的目的,但稍微想一下就知道,直接開根號就行了,用double的精度是足夠的。math.h中的double pow(double,double)真是強大。

時間複雜度:就看pow函數了,不知道它的原理,應該是牛頓迭代法吧~

#include "stdafx.h"
#include <iostream>    // 280K 0MS 
#include <math.h>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	double n,p;  //注意double的取值範圍
	while(cin>>n>>p){
		cout<<pow(p,1/n)<<endl;
	}
	return 0;
}


3. poj2586 Y2K Accounting Bug

題目:巨難懂!!一家奇怪的公司每個月要么盈利s要么盈利d。公司是每連續5個月結算一次,這樣一年就有8次結算,都是虧的。問公司能否盈利,若能求最大盈利,否則輸出Deficit.

分析:也就是對s和d組成的長度為12的序列進行判斷,因為每次結算都是虧的,所以只有五種情況(盈利最大情形)!

時間複雜度O(n)

#include "stdafx.h"
#include <iostream>    //256K 16MS 
using namespace std;

int benif(int s, int d){
	if(4*s-d<0) return 10*s-2*d;   //ssssdssssdss
	if(3*s-2*d<0) return 8*s-4*d;  //sssddsssddss
	if(2*s-3*d<0) return 6*s-6*d;  //ssdddssdddss
	if(s-4*d<0) return 3*s-9*d;    //sddddsddddsd
	return -1;    //dddddddddddd
}

int _tmain(int argc, _TCHAR* argv[])
{
	int s,d;
	while(cin>>s>>d){
		if(benif(s,d)>=0) cout<<benif(s,d)<<endl;
		else cout<<"Deficit" << endl;
	}
	return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值