1. 程式人生 > >中山市第九屆小學生資訊學邀請賽試題 5.合併線段

中山市第九屆小學生資訊學邀請賽試題 5.合併線段

【題目描述】

有一條很長的尺子,上面標記著整數點的座標。如: 現在給出n條線段,每條線段表示為x—y(x和y為整數,x<=y),兩條線段能合併的條件是x—y,y—z,合併為x—z。比如線段2—4和線段4—6可以合併為線段2—6。(線段2—4和線段3—6則不可以合併為線段2—6) 求最終能合併的最長的線段,且輸出這條最長的線段是由多少條小線段組成的。 比如有6條線段:2—7,1—3,3—12,12—20,7—10,4—50 那麼可以合併成以下線段: 1—3,3—12,12—20 長度為20-1=19 由3個線段組成 2—7,7—10 長度為10-2=8 由2個線段組成 4—50 長度為50-4=46 由1個線段組成 那麼最長的一條就是第三個,所以結果為46,1。 需要注意的是:如果有兩條不一樣的連續的線段長度同時為最大,那麼取組成線段數多的一條。 例子:1—5,5—10,1—10,輸出: 9,2

【輸入檔案】

第一行為一個整數n; 第二行到第n+1行,每行兩個整數A B,記錄一條線段的資訊。

【輸出檔案】

輸出一個整數,即能合併成的最長的線段的長度和組成它的線段數。

【輸入輸出樣例1】

e.in e.out 7 1 5 10 12 3 10 2 7 2 10 12 16 7 9 14 3

【樣例1資料提示】

1—5 長度為4 由1個頁段組成 3—10,10—12,12—16 長度為13 由3個頁段組成 2—7,7—9 長度為7 由2個頁段組成 2—10,10—12,12—16 長度為14 由3個頁段組成 所以輸出最長的頁段的長度即14由3個頁段組成

【資料規模】

對於30%的資料:1<=n<=20;對於100%的資料:1<=n<=500 ,0<=A<B<500

其實這道題有點DP的意思了

先進行排序,y來排序。

我們先定義一個s陣列,s[i]表示以線段i結尾的能合併的線段最長為多長 定義c陣列,c[i]表示以線段i結尾的能合併的線段最長的最多要多少條線段

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
	int x,y;
}a[510];
bool cmp(node x,node y){return x.y<y.y;}
int n,s[510],c[510];
int main()
{
scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%d%d",&a[i].x,&a[i].y);//輸入 sort(a+1,a+n+1,cmp);//排序 for(int i=1;i<=n;++i) { s[i]=a[i].y-a[i].x;//初始化,s[i]最長為線段i的長度 c[i]=1;//有一條線段,為線段i for(int j=i-1;j>=1;--j) if(a[j].y==a[i].x) //如果線段i的頭部(x)能和線段j的尾部(y)連線的話 { if(s[i]<s[j]+a[i].y-a[i].x)//判斷是否能更新長度 { //能更新 s[i]=s[j]+a[i].y-a[i].x; c[i]=c[j]+1;//更新長度 } //若不能更新長度 else if(s[i]==s[j]+a[i].y-a[i].x) //判斷是否長度相等 { if(c[i]<c[j]+1)c[i]=c[j]+1; //可以就更新 } } } int maxa=0,maxb=0; //maxa求最長的長度,maxb求合併的線段最長的最多要多少條線段 for(int i=1;i<=n;++i)//更新,不多說 { if(s[i]>maxa) { maxa=s[i];maxb=c[i]; } else if(s[i]==maxa) { if(maxb<c[i])maxb=c[i]; } } printf("%d %d\n",maxa,maxb);//輸出,完結撒花 return 0; }

純程式碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
	int x,y;
}a[510];
bool cmp(node x,node y){return x.y<y.y;}
int n,s[510],c[510];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%d%d",&a[i].x,&a[i].y);
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;++i)
	{
		s[i]=a[i].y-a[i].x;
		c[i]=1;
		for(int j=i-1;j>=1;--j)
			if(a[j].y==a[i].x)
			{
				if(s[i]<s[j]+a[i].y-a[i].x)
				{
					s[i]=s[j]+a[i].y-a[i].x;
					c[i]=c[j]+1;
				}
				else if(s[i]==s[j]+a[i].y-a[i].x)
				{
					if(c[i]<c[j]+1)c[i]=c[j]+1;
				}
			}
	}
	int maxa=0,maxb=0;
	for(int i=1;i<=n;++i)
	{
		if(s[i]>maxa)
		{
			maxa=s[i];maxb=c[i];
		}
		else if(s[i]==maxa)
		{
			if(maxb<c[i])maxb=c[i];
		}
	}
	printf("%d %d\n",maxa,maxb);
	return 0;
}