タイトル説明
学校の門の外には長さLの並木があり、隣接する2本の木々の間の距離は11メートルです。道路を数直線と見なすことができます。道路の一方の端は数直線の00の位置にあり、もう一方の端はLLの位置にあります。数直線上の各整数点は0、1、2です。 、...、L0,1,2、...、L、両方とも木を植えます。
道路には地下鉄を建設するエリアがいくつかあるからです。これらの領域は、数直線上の開始点と終了点で表されます。任意の領域の始点と終点の座標は整数であり、領域間で重複する部分が存在する可能性があることが知られています。次に、これらのエリアのツリー(エリアの端にある2本のツリーを含む)を削除する必要があります。あなたの仕事は、これらの木をすべて取り除いた後、道路に残っている木がいくつあるかを計算することです。
問題解決のアイデア
タイトルを見るだけで、この配列の質問は重なり合う部分の扱いに焦点を当てているように感じます。2つの建設エリアを例にとると、1:2つが重ならない、2:2つが重なる(1つが含まれている)の3つのケースがあります。他の)); 3:部分的に重なっています。最初は、それぞれの状況をリストアップし、重なり合う部分の木の数を足したり引いたりするだけでできると思っていましたが、これは非常に複雑です。
この質問のベストプラクティスは、表記法を使用することです。つまり、最初に配列を作成し、そのすべての要素を「1」にし、各構築領域の値を「0」に変更して、心配する必要がないようにします。重なり合う部分が多すぎることについてツリーを差し引いてください。
コード
#include <stdio.h>
#include <stdlib.h>
int main()
{
int l,m,count=0,i,j;
int a[101][2],lu[10001]={
'\0'}; //a储存所有区域的始末位置; lu储存马路上的树的位置
scanf("%d %d",&l,&m);
for(i=0;i<l+1;i++)
lu[i]=1; //l为马路长度,每棵树距离1米,树的个数为l+1,这里将所有树的位置标记为‘1’
for(i=0;i<m;i++)
{
scanf("%d %d",&a[i][0],&a[i][1]); //对m个区域的始末位置赋值
}
for(i=0;i<m;i++)
{
for(j=a[i][0];j<=a[i][1];j++)
{
lu[j]=0; //将每个区域的所在路的区间的值覆盖为‘0’,表示此段路被用作建设
}
}
for(i=0;i<l+1;i++)
if(lu[i]==1)
count++; //遍历lu,记录'1'的个数,即未被占用的树的数目
printf("%d",count);
}