Saruman's Army POJ - 3069【模拟+贪心】

题意: 输入n个数字,半径r,每个数字可以上一个标记,影响的范围是[x-r,x+r],问最少需要多少次标记,才可以让所有点都被影响。

思路: 先对过程模拟一遍,首先先去找数组里最小的那个数a,在a+r的范围内取找尽可能接近a+r的数组里的数t,然后标记一次,ans++。下一次就从t+r+1的位置循环上面的操作,最后输出ans即可

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=5000;

int a[maxn];
bool vis[maxn];
int ans=0;

int main(void)
{
    int r,n;
    while(cin >> r >> n)
    {
        memset(vis,false,sizeof(vis));
        ans=0;
        if(r==-1 && n==-1)
            break;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]); // 有一个细节是a这个数组对这道题没什么实质的作用。下面vis[a[i]]中,vis套了一个a[i],在数据小的情况下影响不大,当数据大的时候影响就会比较大。
            vis[a[i]]=true;
        }
        int i,j;
        for(i=0; i<=1000;i++)
        {
            if(vis[i]==true)
            {
                int t=-1;
                for(j=i+1; j<=i+r; j++)
                {
                    if(vis[j]==true)
                        t=j;
                }
                if(t!=-1)   i=t+r;// 不加1的原因是for本身有i++了.
                else if(t==-1)  i+=r;
                ans++;
            }
        }
        cout << ans << endl;
    }
    return 0;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值