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

来源:互联网 发布:建立网络共享文件夹 编辑:程序博客网 时间:2024/06/05 20:29

貪心,就是步步為贏。

這是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;   //ssssdssssdssif(3*s-2*d<0) return 8*s-4*d;  //sssddsssddssif(2*s-3*d<0) return 6*s-6*d;  //ssdddssdddssif(s-4*d<0) return 3*s-9*d;    //sddddsddddsdreturn -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;}



 

原创粉丝点击