51nod1744多重排序 (思维)

题目连接:https://www.51nod.com/Challenge/Problem.html#problemId=1774

思路:每次都是1到r进行排序,所以每次后面大的r会覆盖前面较小的r,所以选择出最大的r,然后倒叙维护排序操作,排序也就是反转。具体可见代码理解。

 

#include 
#include 

using namespace std;
#define LL long long
int n, m;
int arr[200001];
int tmp[200001];
int ans[200001];
int t[200001];
int r[200001];

int main()
{
    while(cin >> n >> m)
    {
        memset(tmp, 0, sizeof(tmp));
        memset(ans, 0, sizeof(ans));
        memset(t, 0, sizeof(t));
        memset(r, 0, sizeof(r));
        for(int i = 1 ; i <= n ; i ++)
        {
            scanf("%d", &arr[i]);
            tmp[i] = arr[i];
            ans[i] = arr[i];
        }
        int maxx = -1, x , y;
        for(int i = 1 ; i <= m ; i ++)
        {
            scanf("%d %d", &x, &y);
            t[y] = x;
            r[y] = i;      //后面的操作会覆盖前面的同一位置操作
            maxx = max(maxx, y);
        }
        sort(tmp+1, tmp + 1 + maxx);  //最大的r升序排列
        for(int i = maxx ; i > 0 ; i --)
        {
            if(r[i] < r[i+1])     //后面的升降序操作覆盖前面的操作,只取r最大的
            {
                r[i] = r[i+1];
                t[i] = t[i+1];
            }
        }

        int l = 1, r = maxx;
        for(int i = maxx ; i > 0 ; i --)
        {
            if(t[i] == 2) ans[i] = tmp[l++]; //降序则将前面的数值反转至后面
            else ans[i] = tmp[r--];   //升序正常
        }

        for(int i = 1; i <= n ; i ++)
        {
            cout << ans[i];
            if(i == n) cout << endl;
            else cout << " ";
        }
    }
    return 0;
}

 

你可能感兴趣的:(简单思维)