算式转移(hard)

2019-08-28  本文已影响0人  微糖去冰_

题目描述:
给出一个仅包含加减乘除四种运算符的算式(不含括号),如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

int Partition(vector<int>& nums, int left, int right) {
    int pivot = nums[left], l = left + 1, r = right;
    while (l <= r) {
        if (nums[l] > pivot && nums[r] < pivot)
            swap(nums[l], nums[r]);
        if (nums[l] <= pivot) l++;
        if (nums[r] >= pivot) r--;
    }
    swap(nums[left], nums[r]);
    return r;
}
 
void QuickSort(vector<int> &nums, int lo, int hi) {
    if (hi <= lo) return;
    int seg = Partition(nums, lo, hi);
    QuickSort(nums, lo, seg - 1);
    QuickSort(nums, seg + 1, hi);
}
 
int main(){
    int n; cin>>n;
    vector<int> nums(n, 0);
    vector<char> ops(n, '+');
    for(int i=0; i<n-1; ++i){
        cin >> nums[i];
        cin >> ops[i+1];
    }
    cin >> nums[n-1];
 
    int l=0, r=0;
    while(r<n){
        while(r<n && ops[r] == ops[l]) ++r;
        --r;
        if(ops[l] == '+' || ops[l] == '-'){
            if(r<n-1 && (ops[r+1]=='*' || ops[r+1]=='/'))
                QuickSort(nums, l, r-1);
            else
                QuickSort(nums, l, r);
             
        }
        else if(ops[l] == '*'){
            if(l>0 && (ops[l-1]=='+' || ops[l-1]=='-'))
                QuickSort(nums, l-1, r);
            else
                QuickSort(nums, l, r);
        }
        else if(ops[l] == '/'){
            QuickSort(nums, l, r);
        }
        ++r; l=r;
    }
     
    string ans = to_string(nums[0]);
    for(int i=1; i<n; ++i){
        ans.push_back(' ');
        ans.push_back(ops[i]);
        ans.push_back(' ');
        ans += to_string(nums[i]);
    }
    cout<<ans<<endl;
    return 0;
} 
上一篇 下一篇

猜你喜欢

热点阅读