题意:有一条购物街,这条街相当于一个一维坐标轴,入口处为0,n个商店分别位于从1~n的位置,出口位于n+1处。
输入的ci和di代表:逛商店ci前必须已经逛了商店di。ci,di都是坐标上的位置。
思路: 输入的ci di存到结构体里边,按照ci从小到大排序,如果有交叉的位置直接取并集,比如2 5和3 7,并集就是2 7,7->5->3->2,就可以认为是7->2。若遇到没交叉的地方,把前边的位置走完,以当前位置为开始,继续下边的路程。
代码如下:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#define MAX 0x3f3f3f3f
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double PI = acos(-1);
struct node
{
int c,d;
}a[555];
int cmp(node a,node b)
{
if(a.c!=b.c)
return a.c<b.c;
return a.d<b.d;
}
int main()
{
int n,m;
while(cin >> n >> m){
fori(0,m-1){
cin >> a[i].c >> a[i].d;
}
if(m==0) //m为0,没有限制条件,直接从开始走到结尾
cout << n+1 << endl;
else {
sort(a,a+m,cmp);
int sum = 0,l=a[0].c,r=a[0].d,t=0; //l,r分别代表当前需要逛的商店的最左边的位置和最右边的位置,t为你目前所处的位置
fori(1,m-1){
if(a[i].d>=r&&a[i].c<=r){ //该位置与l~r有交集,且该位置的di>r,更新r
r=a[i].d;
}
else if(a[i].c>r){ //与l~r无交集,直接把l~r走完
sum+=fabs(t-r)+(r-l);
t=l; //更新t
l=a[i].c,r=a[i].d;
}
// else if(a[i].d<=r){
// continue;
// }
}
sum+=fabs(t-r)+(r-l)+(n+1-l);
cout << sum << endl;
}
}
return 0;
}