author:&Carlton
tag:模拟
topic:【NOIP】陶陶摘苹果、校门外的树题解
language:C++
website:洛谷
目录
陶陶摘苹果
校门外的树
我遇到的问题
优秀的题解思路
改后的代码
确实很简单!
#include
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
省去了if判断的步骤,直接使用逻辑值
我原本的思路是:
已知道路长度:”总树量“a,通过分别计算规划道路涵盖的”总树量“b和被反复涵盖的:总树量”c,根据a-(b-c)得到剩下的“树量”。
但抛开全面考虑区间重叠的各个情况带来的复杂不说,一个被反复涵盖的区间被涵盖次数可能>2!也就是说会减去两次c,导致结果出错!
#include
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
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> 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;
}
欢迎指正与分享,谢谢!