给定一个环形数组,询问数组中第x位置与第y位置的最小距离。
因为是环形数组,所以可以顺时针走或是逆时针走,题目只有一组询问,并且n也不大,所以直接模拟即可。时间复杂度为O(N)。
如果涉及到了多组询问,可以用前缀和的方式进行优化。
定义:pre[i]表示前i个数的和
那么i到j的距离就是pre[j−1]−pre[i−1]。环形数组的话可以将数组再复制一遍,这样第1个数与第n个数就会在第n与n+1的位置首尾相接。
预处理前缀和数组的时间复杂度为O(N),询问的时间复杂度为O(1)。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=2e5+10;
int n;
int x,y;
long long a[maxn];
long long sum=0,s=0; 
int main(){
	std::ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>a[i];
		sum+=a[i];
	}
	cin>>x>>y;
	if(x>y) swap(x,y);
	for(int i=x;i<y;++i) s+=a[i];
	cout<<min(s,sum-s);
	
	
	return 0;
}
n = int(input())
sum_total = 0
s = 0
a = input().strip().split(" ")
for i in range(0, n):
    a[i] = int(a[i])
    sum_total += a[i]
x, y = map(int, input().split())
if x > y:
    x, y = y, x
for i in range(x-1, y-1):
    s += a[i]
print(min(s, sum_total - s))
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int maxn = 200010; // maxn is not used in the code
        int n = scanner.nextInt();
        int x, y;
        long[] a = new long[maxn];
        long sum = 0, s = 0;
        for (int i = 1; i <= n; ++i) {
            a[i] = scanner.nextLong();
            sum += a[i];
        }
        x = scanner.nextInt();
        y = scanner.nextInt();
        if (x > y) {
            int temp = x;
            x = y;
            y = temp;
        }
        for (int i = x; i < y; ++i) {
            s += a[i];
        }
        System.out.println(Math.min(s, sum - s));
    }
}
        小美所在的物流公司有一个环形仓储,一共有n个仓储点,小美每天要在这里面搬运货物,十分劳累。
这天,小美又要将货物从第i个仓储点搬运到第j个仓储点了,他想知道,他需要走的最短的路程是多少?
第一行输入一个正整数n,代表仓储点的数量。
第二行输入n个正整数ai,前n−1个数代表顺时针沿着环形仓储走,第i个仓储点到第i+1个仓储点之间的距离:最后一个正整数代表顺时针沿着环形仓储走,第n个仓储点到第1个仓储点的距离
第三行输入两个正整数x和y,代表小美需要将货物从第x个仓储点搬运到第y个仓储点。
1<n<105
1<ai<109
1≤x,y≤n
一个正整数,代表小美需要走的最短距离。
输入
3
1 2 3
1 2
输出
1
输入
5
2 1 3 4 1
1 3
输出
3