版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mirror1997/article/details/86228338
今天舒服了不少。
果然感冒七天好,今天是第五天,感觉快好了。
离拔掉可恨的智齿又近了一步。
把昨天没做出来的做了一下,感觉神清气爽的。
果然做题和身体状态也很有关系。
贪心第二题:
题目:
给定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;
}