A1044 Shopping in Mars (25 points | binary search | upper_bound, attach detailed notes, logical analysis)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_24452475/article/details/100549437

EDITORIAL

  • Ideas analysis
    • Understanding the problem
      • 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.
        • Exactly equal
      • If there is no solution, output i-j for pairs of i ≤ j such that Di + ... + Dj >M with (Di + ... + Dj −M) minimized.
        • Not exactly equal, to pay a minimum price (zoomed sum must be greater than or equal to the value)
    • Simple simulation, two times out.
    • Later sum array increments, find use ⼆ points system
      • I.e., SUM [i] denotes the i-1 to the sum of all numbers -
  • Subject difficult, living with flexible ing

Test Case

  • input:
    16 15
    3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13
    
    output:
    1-5
    4-6
    7-8
    11-11
    
    input:
    5 13
    2 4 5 7 9
    
    output:
    2-4
    4-5
    

ac Code

  • #include <vector>
    #include <iostream>
    using namespace std;
    
    vector<int> sum, result;
    int n, m;
    void binary_searchs(int i, int &j, int &tmpsum)
    {
        int left = i, right = n;
        while(left < right)
        {
            int mid = (left + right)/2;
            if(sum[mid] - sum[i-1] >= m)
                right = mid;
            else
                left = mid + 1;
        }
        j = right;
        tmpsum = sum[j] - sum[i-1];
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        sum.resize(n+1);
        for(int i=1; i<=n; i++)
        {
            scanf("%d", &sum[i]);
            sum[i] += sum[i-1];
        }
        int minans = sum[n];
        for(int i=1; i<=n; i++)
        {
            int j, tmpsum;
            binary_searchs(i, j, tmpsum);
            if(tmpsum > minans) continue;
            if(tmpsum >= m)
            {
                if(tmpsum < minans)
                {
                    result.clear();
                    minans = tmpsum;
                }
                result.push_back(i);
                result.push_back(j);
            }
        }
    
        for(int i=0; i<result.size(); i+=2)
            printf("%d-%d\n", result[i], result[i+1]);
    
        return 0;
    }
    

Learning Code

  • Analysis of the meaning of problems
    • It gives a number of a sequence of numbers S 1, and obtains all the consecutive sequences in the digital value of the sequence S (subscript small intervals left first output point, the left end of the same small dot to the right end of the output).
    • Without such a sequence, and obtains a value just greater than the sub-sequence S (i.e. subsequence and all values ​​greater than S and the value closest S)
    • Half-understand status, there is more time debugging, self-realization of a
      Here Insert Picture Description
    #include<iostream>
    #include<algorithm>
    #define MAX 100001
    using namespace std;
    
    int diamonds[MAX];
    int main()
    {
        int N,M,input;
        while(cin>>N>>M)
        {
            int minlost = 99999999;
            int low = 0;
            bool notFound = true;
            fill(diamonds,diamonds+MAX,0);
    
            for(int i=1; i<=N; i++)
            {
                cin>>diamonds[i];
                diamonds[i]+=diamonds[i-1];
                while(diamonds[i] - diamonds[low]>M)
                {
                    minlost = min(minlost,diamonds[i] - diamonds[low]);
                    low++;
                }
                if(diamonds[i] - diamonds[low] == M)
                {
                    cout<<low+1<<"-"<<i<<endl;
                    notFound = false;
                }
            }
            if(notFound)
            {
                low = 0;
                for(int i=1; i<=N; i++)
                {
                    while(diamonds[i] - diamonds[low]>minlost)
                        low++;
                    if(diamonds[i] - diamonds[low]==minlost)
                    {
                        cout<<low+1<<"-"<<i<<endl;
                    }
                }
            }
        }
        return 0;
    }
    

Knowledge Point Summary

  • lower_bound( begin,end,num)
    • lower_bound( begin,end,num,greater<type>() )
    • First a number greater than or equal num can play digital address
    • There is no return end
  • upper_bound( begin,end,num)
    • upper_bound( begin,end,num,greater<type>() )
    • Num is greater than a first digital
    • There is no return end
  • Code Example 1
  • // lower_bound/upper_bound example
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    int main ()
    {
        int myints[] = {10,20,30,30,20,10,10,20};
        vector<int> v(myints,myints+8);           // 10 20 30 30 20 10 10 20
        vector<int>::iterator low,up;
    
        sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30
    
        low=lower_bound (v.begin(), v.end(), 20); //          ^
        up= upper_bound (v.begin(), v.end(), 20); //                   ^
    
        cout << "lower_bound at position " << int(low- v.begin()) << " " <<  myints[int(low- v.begin())+1] << endl;
        cout << "upper_bound at position " << int(up - v.begin()) << " " << myints[int(up- v.begin())+1] << endl;
    
        return 0;
    }
    

Guess you like

Origin blog.csdn.net/qq_24452475/article/details/100549437