Question 195.pat Grade A Exercise - 1046 Shortest Distance (20 points)


Question 195.pat Grade A Exercise - 1046 Shortest Distance (20 points)


1. The topic

insert image description here

2. Problem solving

This problem is given when the i position is to i+1, that is, the distance from the next position, and finally the distance back to the initial position, thus forming a loop, this kind of "circling phenomenon" problem, we are likely to think of queue simulation To achieve the required shortest distance solution from a certain position to a certain position, deque is used because it can go in both directions. But this will time out and lose points. The code is as follows:

//队列模拟
#include <bits/stdc++.h>

using namespace std;

int len0[100001];
deque<int> q0,q;
int sum_len0;

int main()
{
    
    
    int N;
    cin>>N;
    for(int i=1;i<=N;i++)
    {
    
    
        scanf("%d",&len0[i]);
        sum_len0+=len0[i];
        q0.push_back(i);
    }
    int M;
    cin>>M;
    for(int i=0;i<M;i++)
    {
    
    
        int v1,v2;
        scanf("%d%d",&v1,&v2);
        q=q0;
        while(q.front()!=v1)
        {
    
    
            int tmp=q.front();
            q.pop_front();
            q.push_back(tmp);
        }
        int len=0;
        while(q.front()!=v2)
        {
    
    
            int tmp=q.front();
            q.pop_front();
            len+=len0[tmp];
            q.push_back(tmp);
        }
        int minlen=min(len,sum_len0-len);
        printf("%d\n",minlen);
    }
}

In fact, this question needs to examine the prefix sum and difference. If you think about it, you can find that finding the shortest distance from the previous position to the back position is actually taking the difference between the prefix sum of the prefix sum of the corresponding position in the array and the sum of all distances minus the minimum of that difference (going in the other direction, Because it is a loop, in fact, it is enough to directly sum and subtract). code show as below:

//前缀和与差分
#include <bits/stdc++.h>

using namespace std;

int len0[100001],sum[100001];

int main()
{
    
    
    int N;
    cin>>N;
    for(int i=1;i<=N;i++)
    {
    
    
        scanf("%d",&len0[i]);
        sum[i]=len0[i]+sum[i-1];
    }
    int M;
    cin>>M;
    for(int i=0;i<M;i++)
    {
    
    
        int v1,v2;
        scanf("%d%d",&v1,&v2);
        if(v2<v1)
        {
    
    
            swap(v2,v1);//保证小在前,大在后,因为后面sum是作差得到,sum是递增的,得求出len是正的才行
        }
        int len=sum[v2-1]-sum[v1-1];
        int minlen=min(len,sum[N]-len);
        printf("%d\n",minlen);
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324345632&siteId=291194637