思路一
这道题相当于就是求给定圆上两点,求两点间较小的一段的弧长,在求出一段弧长之后我们直接用周长减去这段弧长就是另外一段的弧长,然后比较两者间较小的一个。
所以对于这道题,首先就是求出 所有编号结点
到 1号结点
的前缀和,然后利用前缀和求出两点之间的距离,这样就求得了一段弧长,然后另一段弧长就是总的长度减去刚刚求得的弧长就得到了。
代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int s[N];
int main(){
int n,m;
cin>>n;
int sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
for(int i=1;i<n;i++) s[i+1] = s[i]+a[i];
cin>>m;
while(m--){
int x,y;
scanf("%d%d",&x,&y);
if(x<y) swap(x,y);
int mind = s[x]-s[y];
if(mind > (sum-mind)) mind = sum-mind;
cout<<mind<<endl;
}
return 0;
}
思路二
当前求的是l
到r
的距离 (l < r),那么l
到r
的距离有两种情况,一种是l
直接到r
的距离,另外一种是l
先走到n
,然后n
再走到1
,再从1
走到l
的距离。
代码
#include<iostream>
using namespace std;
const int N = 1e5+10;
int a[N],s[N];
int main(){
int n,m;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
cin>>m;
while(m--){
int l,r;
scanf("%d%d",&l,&r);
if(l>r) swap(l,r);//注意l要<r
printf("%d\n",min(s[r-1]-s[l-1],s[n]-s[r-1]+s[l-1]));
}
return 0;
}