题意:度度熊在玩一个好玩的游戏。 游戏的主人公站在一根数轴上,他可以在数轴上任意移动,对于每次移动,他可以选择往左或往右走一格或两格。 现在他要依次完成 nn 个任务,对于任务 ii,只要他处于区间 [a_i,b_i][ai,bi] 上,就算完成了任务。 度度熊想知道,为了完成所有的任务,最少需要移动多少次? 度度熊可以任意选择初始位置。
思路:刚开始把区间合并,然后遍历过去,然后找往左还是往右,都往一个方向就在反方向再求sum累加。注意的是当区间为一个点时,必须加上。
思路感觉很简单,就是细节太多了。
#include<cstring> #include<algorithm> #include<vector> #include<map> #include<queue> #include<cstdio> #include<cmath> #define ll long long #define lowbit(x) x&(-x) using namespace std; struct point { ll x; ll y; }a[100010]; int b[100010]; int main() { int t; scanf("%d",&t); while(t--) { memset(b,0,sizeof(b)); int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lld%lld",&a[i].x,&a[i].y); } if(n==1) { printf("0\n"); continue; } ll sum1=0,sum2=0,sum=0; int m=0; ll r1=a[0].x; ll r2=a[0].y; int d; int flag=0; int isleft=2; int u=0; int k=0; for(int i=1;i<n;i++) { if(flag==0) { if(a[i].x>r2) { m=r2; d=r2-r1; flag=1; isleft=0; } else if(r1>a[i].y) { m=r1; d=r2-r1; isleft=1; flag=1; } else { r1=max(r1,a[i].x); r2=min(r2,a[i].y); } // printf("m:::::%d\n",m); } if(flag==1) { if(a[i].x==a[i].y&&a[i].x!=m) { if(a[i].x>m) { if((a[i].x-m)%2==0) { sum+=(a[i].x-m)/2; } else { sum+=(a[i].x-m)/2+1; } isleft=0; } else { if((m-a[i].y)%2==0) { sum+=(m-a[i].y)/2; } else { sum+=(m-a[i].y)/2+1; } isleft=1; } m=a[i].x; } else { // printf("m:%d\n",m); // printf("%lld %lld\n",a[i].x,a[i].y); if(a[i].x>m) { if(isleft==1) { if((m-a[i-1].y)%2==0) { sum+=(m-a[i-1].y)/2; } else { sum+=(m-a[i-1].y)/2+1; } m=a[i-1].y; } isleft=0; } if(a[i].y<m) { if(isleft==0) { if((a[i-1].x-m)%2==0) { sum+=(a[i-1].x-m)/2; } else { sum+=(a[i-1].x-m)/2+1; } m=a[i-1].x; } isleft=1; } } // printf("sum:%d\n",sum); } } if(isleft==0) { if((a[n-1].x-m)%2==0) { sum+=(a[n-1].x-m)/2; } else { sum+=(a[n-1].x-m)/2+1; } } if(isleft==1) { if((a[n-1].y-m)%2==0) { sum+=(m-a[n-1].y)/2; } else { sum+=(m-a[n-1].y)/2+1; } } printf("%lld\n",sum); } }
没过,不知道哪错了。也许思路错了。