1. 程式人生 > >強行刷段位第八天

強行刷段位第八天

今天舒服了不少。

果然感冒七天好,今天是第五天,感覺快好了。

離拔掉可恨的智齒又近了一步。

 

把昨天沒做出來的做了一下,感覺神清氣爽的。

果然做題和身體狀態也很有關係。


貪心第二題:

題目:

 給定x軸上的N(0<N<100)條線段,每個線段由它的二個端點a_I和b_I確定,I=1,2,……N.這些座標都是區間(-999,999)的整數。有些線段之間會相互交疊或覆蓋。請你編寫一個程式,從給出的線段中去掉儘量少的線段,使得剩下的線段兩兩之間沒有內部公共點。所謂的內部公共點是指一個點同時屬於兩條線段且至少在其中一條線段的內部(即除去端點的部分)。

輸入描述:

輸入第一行是一個整數N。接下來有N行,每行有二個空格隔開的整數,表示一條線段的二個端點的座標。

輸出描述:

輸出第一行是一個整數表示最多剩下的線段數。

樣例輸入:

3

6  3

1  3

2  5

樣例輸出:

2

資料範圍及提示:

0<N<100

我的答案:

這道題昨天沒做出來的時候看了看別人的答案,腦子暈暈的,也沒看出個所以然。看見有人說用堆,從沒寫過堆的我化身退堂鼓表演藝術家。

說到底還是應該抓住到底哪些線段是一定會加入的。抓住確定的,去解決不確定的。

昨天就是沒想出來哪些是一定加入的,

今天一早起來舒爽了不少,刷牙的時候想了一下,當然是那些和所有線段都不重疊的啦~

所以就想出了下面這種分三步的辦法。雖然要寫100行,但勝在簡單易懂~

1.計算每條線段到底和多少條線段重疊,稱為重疊數

2.按重疊數升序排列

3.按次序依次判斷,如果此線段加入後無重疊,則新增

其實不應該用二維陣列的,應該寫結構體更清楚一點。

不過我懶,懶得改了。

 

另外,我都上學這麼久了,怎麼還總是把“==”寫成“=”呀。。。出現這種問題是智障嗎。。。

 

程式碼如下:

#include <iostream>
using namespace std;
int arr[100][3];
int add[100];

void sort(int arr[][3],int n)  //氣泡排序(按照重疊數升序) 
{
	int i=0,j=0,temp=0;
	for(i=n-1;i>=1;i--)
	{
		for(j=1;j<=i;j++)
		{
			if(arr[j-1][2]>arr[j][2])
			{
				temp=arr[j-1][0];
				arr[j-1][0]=arr[j][0];
				arr[j][0]=temp;
				
				temp=arr[j-1][1];
				arr[j-1][1]=arr[j][1];
				arr[j][1]=temp;
				
				temp=arr[j-1][2];
				arr[j-1][2]=arr[j][2];
				arr[j][2]=temp;
			}
		}
	}
}

void overlapnum(int arr[][3],int n) //計算重疊數 
{
	int i=0,j=0,temp=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			if(j==i)  continue;
			if(arr[i][0]>=arr[j][0] && arr[i][0]<arr[j][1]) temp++;
			else if(arr[i][1]>arr[j][0] && arr[i][1]<=arr[j][1]) temp++;
			else if(arr[i][0]<=arr[j][0] && arr[i][1]>=arr[j][1]) temp++;
		}
		arr[i][2]=temp;
		temp=0;
	}
 } 

int judge(int arr[][3],int add[],int n) //判斷能不能重疊,如果就新增,最終返回新增進去的最大條數; 其中arr按重疊數升序 
{
	int i=0,j=0;
	int flag=0;
	int result=1;
		
	add[0]=1;
	for(i=1;i<n;i++)
	{
		flag=0;
		for(j=0;j<i;j++)
		{
			if(add[j]==1)
			{
			    if(arr[i][0]>=arr[j][0] && arr[i][0]<arr[j][1]) flag=1;
		     	else if(arr[i][1]>arr[j][0] && arr[i][1]<=arr[j][1]) flag=1;
			    else if(arr[i][0]<=arr[j][0] && arr[i][1]>=arr[j][1]) flag=1;
			
			    if(flag==1) break;
			}
		}
		if(flag==0)
		{
			add[i]=1;
			result++;
		}
	}	
	return result;
 } 

int main ()
{
	int n=0,i=0,temp=0,sum=0,result=0;
	cin>>n;
	
	for(i=0;i<n;i++)  //輸入線段,並將靠近原點的點作為起始點 
	{
		cin>>arr[i][0]>>arr[i][1];
		if(arr[i][0]>arr[i][1])
		{
			temp=arr[i][0];
			arr[i][0]=arr[i][1];
			arr[i][1]=temp;
		}
	}
	
    overlapnum(arr,n);  
    sort(arr,n);
    sum=judge(arr,add,n);
	cout<<sum;
		
	return 0;	
 }