【题解】砍树

博客围绕农场砍树问题展开,Farmer John要砍N棵排成直线的树,可用炸弹摧毁,炸弹能压倒两边矮树。题目给出输入输出格式及样例,题解指出从最高的树开始炸可使用最少炸弹,还给出了参考链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

        为了在农场的一块土地上种奶牛吃的草,Farmer John必须要把前面的N棵树砍掉,这些树紧密地排成一条直线,并且用1-N编号标识,每一棵树都有自己的高度Hi(1≤Hi≤10000)。

        Farmer John想用炸弹来摧毁这些树,这种炸弹除了能摧毁安装了炸弹的那棵树以外还能传递压倒两边矮于这一棵树的所有邻近树,直到遇到一棵不低于这一棵树的树为止。

        例如:一排树的高度如下:1 2 5 4 3 3 6 6 2,如果Farmer John在第三棵树上装炸弹(高度为5),那么第二棵树也同样给压倒(高度为2<5),第一棵树也同样倒下(高度为1<2),再来看另一边第四棵树(高度为4<5)和第五棵树(高度为3<4)同样也给压倒。剩下的状态为:× × × × × 3 6 6 2,接下来在第七和第八棵树上安装炸弹就可以把剩下的树毁掉。

       请你帮助Farmer John利用最少的炸弹把这些树毁掉。

 

输入格式

        第一行,一个整数N(1≤N≤50000);

        第二行至第N+1行,包含各棵树的高度Hi。

 

输出格式

第一至第?行,每一行为一个整数,代表安装炸弹的树的编号,按照升序输出。

 

输入样例

9

1

2

5

4

3

3

6

6

2

 

输出样例

3

7

8

 

题解

        容易想到,从最高的树开始炸即可。

#include <iostream>
#include <cstdio> 
#include <algorithm>
#include <queue>
#define MAXN 50001 

using namespace std;

int n;
int a[MAXN];
struct node
{
    int hei;
    int idx;
}b[MAXN];
bool cmp(node a, node b)
{
    return a.hei > b.hei;// 从高的树开始炸 
}
priority_queue<int, vector<int>, greater<int> > q;// 答案从小到大排序 

int main()
{
    scanf("%d", &n);
    for(register int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        b[i].hei = a[i];
        b[i].idx = i;
    }
    sort(b + 1, b + 1 + n, cmp); 
    for(register int i = 1, c; i <= n; i++)
    {
        if(a[b[i].idx])
        {
            c = a[b[i].idx];
            for(register int j = b[i].idx - 1; j >= 1; j--)
            {// 压到左边的数 
                if(a[j] < c)
                {
                    if(a[j])
                    {
                        c = a[j];
                        a[j] = 0;
                    }
                    else break;
                }
                else break;
            }
            c = a[b[i].idx];
            for(register int j = b[i].idx + 1; j <= n; j++)
            {//压倒右边的数 
                if(a[j] < c)
                {
                    if(a[j])
                    {
                        c = a[j];
                        a[j] = 0;
                    }
                    else break;
                }
                else break;
            }
            q.push(b[i].idx);
            a[b[i].idx] = 0;
        }
    }
    while(!q.empty())
    {
        printf("%d", q.top());
        q.pop();
        if(!q.empty()) putchar('\n'); 
    }
    return 0;
}
参考程序

 

转载于:https://www.cnblogs.com/kcn999/p/10799504.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值