题意:设置哨兵位置,给一堆点,每个哨兵可以覆盖m米的地方(向前或向后),问如果把所有的点都覆盖到需要最少多少个哨兵点。
给一组数据,第一行两个数哨兵范围m和点的数量n
第二行n个点的位置
10 7
70 30 1 7 15 20 50
显然,先得排个序,便于从左到右找哨兵合适的位置
1 7 15 20 30 50 70
然后,考虑一下这个题解决的关键点:需要尽可能少的哨兵点,那就需要每个哨兵能照顾到尽可能多的点。
从左边第一个点开始考虑,那哨兵放在能罩住它这个点并且尽可能远离这个点(靠近右边)的位置最合适,那就往右边找,在10以内的只有7这个点,那就在7这里放一个哨兵,再看看以7这个点能辐射到的其他点有哪些,只有15,于是下一次考虑放哨兵的位置就从能罩住20这个点(15之后)的位置开始即可。依此类推,就可以得到最少需要哨兵点的个数了。
描述以上操作的关键代码如下:
while(t < n)
{
l = t++;
while( a[t] - a[l] <= m && t < n ) t++; //找哨兵应该出现的位置
r = t-1;
while(a[t] - a[r] <= m && t < n) t++;//找这个哨兵往后辐射的范围内最后一个有效点
//,方便对下一个哨兵位置进行寻找
ans++;
}
AC代码如下:
java
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = new int[3000];
Scanner cin = new Scanner(System.in);
int m = 0,n = 0,ans = 0,l = 0,r = 0,t = 0;
while(cin.hasNext())
{
m = cin.nextInt();
n = cin.nextInt();
if(m == -1 && n == -1)break;
for(int i = 0 ;i < n ; i++)
a[i] = cin.nextInt();
Arrays.sort(a,0,n);
t = 0;
ans = 0;
while(t < n)
{
l = t++;
while( a[t] - a[l] <= m && t < n ) t++;
r = t-1;
while(a[t] - a[r] <= m && t < n) t++;
ans++;
}
System.out.println(ans);
}
}
}
C++
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[2000],m,n;
void input()
{
for(int i = 0 ; i < n ; i++)
cin>>a[i];
sort(a,a+n);
}
void solve();
int main()
{
#ifdef H_R
freopen("in.txt","r",stdin);
#endif // H_R
ios::sync_with_stdio(false);
cin.tie(false);
while(cin>>m>>n)
{
if(m == -1 && n == -1)
break;
input();
solve();
}
return 0;
}
void solve()
{
int ans = 0;
int l = 0,r = 0,t = 0;
while( t < n )
{
l = t++;
while(a[t] - a[l] <= m && t < n )
t++;
r = t-1;
while(a[t] -a[r] <= m && t < n )
t++;
ans++;
}
printf("%d\n",ans);
}