PAT Grade 1044 Shopping in Mars (25 minutes) (sliding window, foot emulated, may be two points)

1044 Shopping in Mars (25 points)
 

Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M$). When making the payment, the chain can be cut at any position for only once and some of the diamonds are taken off the chain one by one. Once a diamond is off the chain, it cannot be taken back. For example, if we have a chain of 8 diamonds with values M$3, 2, 1, 5, 4, 6, 8, 7, and we must pay M$15. We may have 3 options:

  1. Cut the chain between 4 and 6, and take off the diamonds from the position 1 to 5 (with values 3+2+1+5+4=15).
  2. Cut before 5 or after 6, and take off the diamonds from the position 4 to 6 (with values 5+4+6=15).
  3. Cut before 8, and take off the diamonds from the position 7 to 8 (with values 8+7=15).

Now given the chain of diamond values and the amount that a customer has to pay, you are supposed to list all the paying options for the customer.

If it is impossible to pay the exact amount, you must suggest solutions with minimum lost.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤), the total number of diamonds on the chain, and M (≤), the amount that the customer has to pay. Then the next line contains N positive numbers D1​​DN​​ (Di​​103​​ for all ,) which are the values of the diamonds. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print i-j in a line for each pair of i ≤ j such that Di + ... + Dj = M. Note that if there are more than one solution, all the solutions must be printed in increasing order of i.

If there is no solution, output i-j for pairs of i ≤ j such that Di + ... + Dj > with (Di + ... + Dj −) minimized. Again all the solutions must be printed in increasing order of i.

It is guaranteed that the total value of diamonds is sufficient to pay the given amount.

Sample Input 1:

16 15
3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13

Sample Output 1:

1-5
4-6
7-8
11-11

Sample Input 2:

5 13
2 4 5 7 9

Sample Output 2:

2-4
4-5

 

Meaning of the questions:

 Find and not less than a given value, but as small as possible all substring

 

answer:

 After two pointers pointing to the head and tail substring, specifically looking at the code (with optimization, for example, a substring found to meet the requirements, next scan right a left pointer, the starting position of the right pointer remains at a the pointer to the right position).

1. emulated feet, if needed to obtain the sum of the range is greater than the pay, the head deleted

2. If you get a comprehensive range of less than pay, increasing the tail

3. Note that the border situation and not equal, you can view the details of the code

4. Use of a recorded answer minAns variable values

 

AC Code:

#include <the iostream> 
#include <algorithm> 
#include <Vector> 
#include <Queue> 
#include <Map> 
#include < String > 
#include <CString>
 the using  namespace STD;
 int A [ 100005 ];
 int ANS [ 100005 ] ; // array of test points on the small opening 3 has however 
int K = 0 ;
 int n-, m;
 int Cha = 0x7FFFFFFF ;
 int main () { 
    CIN >> >> n- m;
     for (int i=1;i<=n;i++){
        cin>>a[i];
    }
    int r=1,l=1;
    int s=0;
    while(r<=n){
        while(s<m&&l<=n){
            s+=a[l];
            l++;
        }
        if(s<m){
            break;
        }
        else if(s<cha){
            k=0;
            ans[++k]=r;
            ans[++k]=l-1;
            cha=s;
        }else if(s==cha){
            ans[++k]=r;
            ans[++k]=l-1;
        }
        s-=a[r];
        r++;
    }
    for(int i=1;i<=k;i+=2){
        cout<<ans[i]<<"-"<<ans[i+1]<<endl;
    }
    return 0;
} 

 

Can also be used binary:

Since all diamond value is positive, therefore, accumulated from the beginning to the value chain and a position of constant positive value when reading;

Starting from the first position to find a position exactly equal to or greater than the target value by dichotomy, comparing and calculating the difference;

If the difference is smaller data sets, the update record; just as a data set to find a difference, added record;

Title required output according to the result, and returns a zero value.

#include<cstdio>
#include<fstream>
const int N=100010;
int sum[N];
int n, S, nears=100000010;
 
int upper_bound(int L, int R, int x){
    int left=L, right=R, mid;
    while(left<right){
        mid=(left+right)/2;
        if(sum[mid]>x){
            right=mid;
        } else{
            left=mid+1;
        }
    }
    return left;
}
 
int main(){
//    freopen("d://in.txt","r",stdin);
    scanf("%d%d", &n, &S);
    sum[0]=0;
    for(int i=1; i<=n; i++){
        scanf("%d", &sum[i]);
        sum[i]+=sum[i-1];
    }
    
    for(int i=1; i<=n; i++){
        int j=upper_bound(i, n+1, sum[i-1]+S);
        if(sum[j-1]-sum[i-1]==S){
            nears=S;
            break;
        } else if(j<=n && sum[j]-sum[i-1]<nears){
            nears=sum[j]-sum[i-1];
        }
    }
    
    for(int i=1; i<=n; i++){
        int j=upper_bound(i, n+1, sum[i-1]+nears);
        if(sum[j-1]-sum[i-1]==nears){
            printf("%d-%d\n", i, j-1);
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/caiyishuai/p/11446367.html