题意:最开始可以选择任意位置,在一个坐标轴上,依次走到一个区间里面,可以选择走一步两步,求最小步数。
思路:贪心,刚开始合并区间,确定初始位置以及方向。往右走肯定到左端点,往左走先到右端点,判断下个区间的和下下个区间的方向是否一致,一致如果到是奇数,则当偶数处理位置,反之,仍然走到
端点上。wa了很多次,细节没注意好。
#include<iostream> #include<algorithm> #include<string> #include<cstring> #include<cstdio> #include<cmath> #include<map> #include<queue> #define ll long long using namespace std; const int N=1100000; int l[1100],r[1100]; int t,n; struct Node { int a,b; }e[1100]; int main() { scanf("%d",&t); while(t--) { memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&e[i].a,&e[i].b); } int ans=0; l[0]=e[0].a; r[0]=e[0].b; int j=0; for(int i=1;i<n;i++) { if(e[i].a>=r[j]||e[i].b<=l[j]) { j++; l[j]=e[i].a; r[j]=e[i].b; } else if(e[i].a>l[j]&&e[i].b<r[j]) { l[j]=e[i].a; r[j]=e[i].b; } else if(e[i].a>l[j]&&e[i].b>r[j]&&e[i].a<r[j]) { l[j]=e[i].a; } else if(e[i].a<l[j]&&e[i].b>l[j]&&e[i].b<r[j]) { r[j]=e[i].b; } } int s; if(l[1]>r[0]) { s=r[0]; } else { s=l[0]; } int tmp; for(int i=1;i<=j;i++) { if(r[i]<l[i-1]) { tmp=s-r[i]; s=r[i]; if(tmp%2&&l[i]<s&&i+1<=j&&r[i+1]<l[i]) { tmp++; s--; } } else if(l[i]>r[i-1]) { tmp=l[i]-s; s=l[i]; if(tmp%2&&r[i]>s&&i+1<=j&&l[i+1]>r[i]) { tmp++; s++; } } if(tmp%2) ans+=tmp/2+1; else ans+=tmp/2; } printf("%d ",ans); } return 0; }