目录
- Poj1328–Radar Installation
- Poj1042–Gone Fishing
- 最优服务次序
- 汽车加油问题
- 删数问题
Poj1328–Radar Installation
题目链接:Poj1328
题目大意:
就是给你n个岛,在x轴的上方,要你在x轴上选择最少的雷达数覆盖这n个岛,雷达的范围是d,输入n,d,并给出n个岛的(x,y)坐标,求出最少的雷达数,来覆盖这些岛屿。
解析:
利用贪心的选择,求出每个岛屿的两边所能覆盖岛的位置,然后把每个岛屿的这两个位置按照后面那个(结束的位置)排序,从第一个贪心选择就可以(和活动安排选择类似)。
import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
/**
* 题目链接 : http://poj.org/problem?id=1328
* @author 郑鑫
*/
public class RadarInstallation { //提交的时候改成Main
public static final int maxn = 1000 + 10;
private static class Rad implements Comparable<Rad>{
double l,r;
public Rad() {
}
public Rad(double l,double r){
this.l = l;
this.r = r;
}
@Override
public int compareTo(Rad o) {
return r > o.r ? 1: (r == o.r ? 0: -1);
}
}
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int kase = 0;
while(cin.hasNext()){
int n = cin.nextInt();
int d = cin.nextInt();
if(n == 0 && d == 0)break;
System.out.print("Case " +(++kase) +": ");
ArrayList<Rad>rad = new ArrayList<Rad>();
boolean flag = true;
for(int i = 0; i < n; i++){
int x = cin.nextInt();
int y = cin.nextInt();
rad.add(new Rad(x - Math.sqrt(d*d*1.0 - (y*y*1.0)),x + Math.sqrt(d*d*1.0 - (y*y*1.0))));
if(y > d)flag = false;
}
if(!flag){
System.out.println(-1);
continue;
}
Collections.sort(rad);
double End = rad.get(0).r;
int sum = 1;
for (int i = 1; i < n; i++) {
if (rad.get(i).l > End) {
sum++;
End = rad.get(i).r;
}
}
System.out.println(sum);
}
}
}
Poj1042–Gone Fishing
题目链接:Poj1042
题目大意:
John现有h个小时的空闲时间,他打算去钓鱼。钓鱼的地方共有n个湖,所有的湖沿着一条单向路顺序排列(John每在一个湖钓完鱼后,他只能走到下一个湖继续钓),John必须从1号湖开始钓起,但是他可以在任何一个湖结束他此次钓鱼的行程。题目以5分钟作为单位时间,John在每个湖中每5分钟钓的鱼数随时间的增长而线性递减。每个湖中头5分钟可以钓到的鱼数用fi表示,每个湖中相邻5分钟钓鱼数的减少量用di表示,John从任意一个湖走到它下一个湖的时间用ti表示。求一种方案,使得John在有限的h小时中可以钓到尽可能多的鱼。
解析
枚举John结束钓鱼的点,先把到这个点所需要的时间减去,然后在从0~这个点中每次贪心选取最大的,把在这里呆的时间叠加,并把相应的剩余量求出来。
import java.io.BufferedInputStream;
import java.util.Scanner;
public class GoneFishing { //提交时改成Main
private static final int maxn = 100 + 10;
private static final int INF = 1000000;
public static void main(String[] args){
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int[] f = new int[maxn],d = new int[maxn],t = new int[maxn];
while(cin.hasNext()){
int n = cin.nextInt();
if( n == 0 )break;
int h = cin.nextInt();
for(int i = 0; i < n; i++)f[i] = cin.nextInt();
for(int i = 0; i < n; i++)d[i] = cin.nextInt();
for(int i = 0; i < n-1; i++)t[i] = cin.nextInt();
int Time = 12 * h;
int nowT,nowF,ans = -INF;
int[] leftF = new int[n+1];
int[] stayT = new int[n+1];
int[] ansStay = new int[n+1];
for(int i = 0; i < n; i++){
nowT = Time; nowF = 0;
for(int j = 0; j < n; j++)stayT[j] = 0;
for(int j = 0; j < i; j++){
nowT -= t[j];
leftF[j] = f[j];
}
leftF[i] = f[i];
for(int j = 0; j < nowT; j++){
int maxx = -INF,maxk = -1;
for(int k = 0; k <= i; k++){
if(leftF[k] > maxx){
maxx = leftF[k];
maxk = k;
}
}
stayT[maxk]++;
nowF += maxx;
leftF[maxk] = Math.max(0,leftF[maxk] - d[maxk]);
}
if(nowF > ans){
ans = nowF;
for(int j = 0; j < n; j++)ansStay[j] = stayT[j];
}
}
System.out.print(ansStay[0] * 5);
for (int i = 1; i < n; i++)System.out.print(", " + ansStay[i] * 5);
System.out.println();
System.out.println("Number of fish expected: " + ans + "\n");
}
}
}
最优服务次序
题目
解析
直接排序贪心选择小的。累加等待时间即可。
import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;
/**
* 题目 : 最优服务次序问题
* @author 郑鑫
*/
public class BestSeverOrder {
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int n = cin.nextInt();
int[] t = new int[n+1];
for(int i = 1; i <= n; i++)t[i] = cin.nextInt();
Arrays.sort(t); //注意Arrays.sort是从1开始排序
for(int i = 2; i <= n; i++)t[i] += t[i-1];
double sum = 0;
for(int i = 1; i <= n; i++)sum += t[i];
System.out.println(sum / n);
}
}
汽车加油问题
题目
解析
比较简答的贪心,没了就加,够就不加。
import java.io.BufferedInputStream;
import java.util.Scanner;
/***
* 汽车加油问题
* @author 郑鑫
*/
public class CarOils {
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int n = cin.nextInt();
int k = cin.nextInt();
int[] d = new int[k+2];
for(int i = 0; i < k+1; i++)d[i] = cin.nextInt();
int nowO = n,sum = 0;
for(int i = 1; i < k+1; i++){
if(d[i] > n ){
System.out.println("No Solution!");
System.exit(0);
}
if(nowO > d[i])nowO -= d[i];
else{
nowO = n - d[i];
sum++;
}
}
System.out.println(sum);
}
}
删数问题
题目
解析
每次删除第一个当前数比后面数大的数,最后得到的就是最小的数(贪心选择)。
import java.io.BufferedInputStream;
import java.util.Scanner;
/**
* 删数问题
* @author 郑鑫
*/
public class DeleteNum {
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
String s = cin.nextLine();
int k = cin.nextInt();
int[] a = new int[s.length() + 1];
int len = s.length();
for(int i = 0; i < s.length(); i++) a[i] = s.charAt(i) - '0';
for( ; k > 0; k--){
int i;
for(i = 0; i < len-1 && a[i] <= a[i+1]; i++);
if(i != len - 1){
for(int j = i; j < len - 1; j++)a[j] = a[j+1];
len--;
}
//for(int j = 0 ;j < len; j++)System.out.print(a[j]);System.out.println();
}
int i;
for(i = 0; i < len; i++)if(a[i] != 0)break; //去除前导0
for(; i < len; i++)System.out.print(a[i]);
System.out.println();
}
}