【NOIP】陶陶摘苹果、校门外的树题解

7 篇文章 0 订阅

author:&Carlton

tag:模拟

topic:【NOIP】陶陶摘苹果、校门外的树题解

language:C++

website:洛谷


目录

陶陶摘苹果

校门外的树

我遇到的问题        

优秀的题解思路

改后的代码


陶陶摘苹果

        

        确实很简单!

#include <iostream>
using namespace std;

int main()
{
    int a[10],i,hand,high,num=0;
    for(i=0;i<10;i++)
    {
        cin>>a[i];
    }
    cin >> hand;
    high=30+hand;
    for(i=0;i<10;i++)
    {
        if(high>=a[i])
        {
            num++;
        }
    }
    cout << num << endl;
    return 0;
}

        题解有个优化点很有意思:num+=!(H<height[i]);

        省去了if判断的步骤,直接使用逻辑值

校门外的树

我遇到的问题        

        我原本的思路是:

        已知道路长度:”总树量“a,通过分别计算规划道路涵盖的”总树量“b和被反复涵盖的:总树量”c,根据a-(b-c)得到剩下的“树量”。

        但抛开全面考虑区间重叠的各个情况带来的复杂不说,一个被反复涵盖的区间被涵盖次数可能>2!也就是说会减去两次c,导致结果出错!

#include <iostream>
using namespace std;

int main()
{
    int l, m, start[100], end[100], i, j, sum = 0, extra = 0;  //确保数组有足够空间存储道路数据
    cin >> l >> m;
    for (i = 0; i < m; i++)
    {
        cin >> start[i] >> end[i];  //存储各道路数据
        sum += end[i] - start[i] + 1;    //在全都不重合的情况下求涵盖的“总树量”
    }
    //计算重合情况下涵盖的“总树量”,它们是多算的
    //使用双循环
    for (i = 0; i < m - 1; i++)
    {
        for (j = i + 1; j < m; j++)
        {
            //重合的情况
            if (!(start[i] > end[j] || end[i] < start[j]))
            {
                //i代表的区域比j区靠左时或者包括j区时
                if (start[i] <= start[j])
                {
                    if (end[i]>=end[j])
                    {
                        extra += end[j] - start[j] + 1;
                    }
                    else
                    {
                        extra += end[i] - start[j] + 1;
                    }
                }
                //i代表的区域比j区靠右或者被j区包括
                else
                {
                    //如果i区完全在j区里
                    if (end[j]>=end[i])
                    {
                        extra += end[i] - start[i] + 1;
                    }
                    //i区并不是完全在j区里
                    else
                    {
                        extra += end[j] - start[i] + 1;
                    }
                }
            }
        }
    }
    sum -= extra;     //减去多算的“树量”
    cout << l + 1 - sum << endl;      //返回的是剩下的“树量”
    return 0;
}

百思不得其解,向其他大神学习一下吧!

优秀的题解思路

        使用标记,模拟砍树。全部树初始标记为0,要砍的树标记为1,分别循环遍历数组即可解决问题。🤔

改后的代码

        注意虽然数据最多有10000棵树,但l可能是10000,道路数据也可以达到10000,数组置0即所有可能的树初始标记为0

#include <iostream>
using namespace std;

int main()
{
    int l,m;
    cin >> l >> m;  //道路长度,道路数量
    int i,a[10001]={0};     //数据最多有10000棵树,但l可能是10000,道路数据也可以达到10000,数组置0即所有可能的树初始标记为0
    int start,end,j;
    for(i=0;i<m;i++)
    {
        cin >> start >> end;
        for(j=start;j<=end;j++)
        {
            a[j]=1;     //给这些道路涵盖的树标上1
        }
    }
    int n=0;
    for(i=0;i<=l;i++)
    {
        if(!a[i])   //如果树没有被标记过
        {
            n++;
        }
    }
    cout << n << endl;
    return 0;
}

欢迎指正与分享,谢谢!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值