滴滴筆試--算術轉移(20190827)

 

題目描述:
給出一個僅包含加減乘除四種運算符的算式(不含括號),如1+2*3/4,在保持運算符順序不變的狀況下,如今你能夠進行若干次以下操做:若是交換相鄰的兩個數,表達式值不變,那麼你就能夠交換這兩個數。

 

如今你能夠進行任意次操做,使得算式的數字序列字典序最小,而後輸出結果,數字之間的字典序定義爲若a<b則a的字典序小於b。

 

輸入
第一行包含一個整數n,表示算式的長度,即包含n個數字和n-1個運算符。(1≤n≤100000)。

 

第二行包含一個含有n個非0整數和n-1個運算符的算式,整數與運算符用空格隔開,運算符包括「+,-,*,/」,整數的絕對值不超過1000。

 

輸出
按要求輸出字典序最小的表達式,數字與符號之間用空格隔開。

樣例輸入
6
3 + 2 + 1 + -4 * -5 + 1
樣例輸出
1 + 2 + 3 + -5 * -4 + 1
 

思路:參考自
先用兩個數組來存儲數字(opNum)和這個數字以前的操做符(opChar)。其中ops第一個元素固定是'+',由於第一個數沒有符號。例如樣例就會獲得以下的兩個數組: ios

索引 0 1 2 3 4 5
nums 3 2 1 -4 -5 1
ops + + + + * +

接着用兩個指針 l 和 r,一段一段地找ops中連續的操做符,例如樣例中就會得出「l=0,r=3; l=4,r=4; l=5,r=5」三段。
接着根據一套規則來肯定 l 和 r 區間內哪些元素是須要進行排序,以實現字典序最小:
  • 若是ops[l]是加號或減號
  1. 這段區間下一個操做符是'*'或者‘/’,那麼要排序的區間是[l, r-1]; 想一想相似5+4+3+2+1*5的狀況
  2. 這段區間下一個操做符是'-',那麼要排序的區間是[l, r];想一想相似5+4+3+2+1-5的狀況
  3. 這裏不須要考慮區間前一個操做符是*、/,-,要排序的區間確定是[l, r],可參考5*4+1+2+3的狀況  (故2,3歸爲else語句便可)
  • ops[l]是乘號
  1. 區間前一個操做符是'+'或者‘-’,那麼要排序的區間是[l-1, r];想一想相似1+5*4*3*2*1的狀況
  2. 區間前一個操做符是‘/’,那麼要排序的區間是[l, r];想一想相似1/5*4*3*2*1的狀況
  • ops[l]是除號
  1. 不論什麼狀況,要排序的區間都是[l, r];
以上遍歷一套,就能夠獲得答案了
代碼:
#include<iostream>
#include<vector>
#include<string> 
#include<algorithm>
using namespace std;

int Partition(vector<int> &nums, int l, int r){
    int pivot = nums[l];
    while(l<r){
        while(l<r && pivot<=nums[r]) 
            --r;
        nums[l] = nums[r];
        while(l<r && pivot>=nums[l]) 
            ++l;
        nums[r] = nums[l];
    }
    nums[l] = pivot;
    return l;
}

void QuickSort(vector<int> &nums, int l, int r){
    if(l<r){
        int mid = Partition(nums, l, r);
        QuickSort(nums, l, mid-1);
        QuickSort(nums, mid+1, r);
    }
}

int main()
{
    int n;
    cin>>n;
    vector<int> opNum(n, 0);
    vector<char> opChar(n, '+');
    for(int i=0;i<n-1;i++){
        cin>>opNum[i];
        cin>>opChar[i+1];
    }
    cin>>opNum[n-1];
    

    int l=0, r=0;
    while(r<n){
        while( r<n && opChar[l]==opChar[r]){
            r++;
        }
        r--;
        //cout<<l<<" "<<r<<endl;
        if(opChar[l]=='*' ){
            if(l-1>=0 && (opChar[l-1]=='+' || opChar[l-1]=='-'))
                QuickSort(opNum, l-1, r);
            else
                QuickSort(opNum, l, r);
        }else if(opChar[l]=='+' || opChar[l]=='-'){
             if(r+1<n-1 && (opChar[r+1]=='*' || opChar[r+1]=='|'))
                 QuickSort(opNum, l, r-1);
             else
                 QuickSort(opNum, l, r);
                 
        }else if(opChar[l]=='/'){
            QuickSort(opNum, l, r);
        }
        r++;
        l = r;
    }
    for(int i=0;i<n-1;i++){
        cout<<opNum[i]<<" ";    
        cout<<opChar[i+1]<<" ";
    }
    cout<<opNum[n-1]<<endl;
    return 0;
    //3 + 2 + 1 + -4 * -5 + 1  ---> 1 + 2 + 3 + -5 * -4 + 1
}
相關文章
相關標籤/搜索