SCU4504 奶牛合影 最小表示法

Time Limit: 1000 MS    Memory Limit: 131072 K 

Description

约翰有N头奶牛,有一天,他想让所有奶牛排成一排照一张全家福。 但是奶牛毕竟是奶牛,颜值的瑕疵无可避免,每头奶牛都有一个瑕疵度。 由于约翰千载难逢才会让奶牛们拍一次合照,他希望整个队列尽可能美观。 对于两个奶牛队列美观度的比较方法是: 从头(从左侧)开始比较,如果第i位置上奶牛的瑕疵度不一样那么谁的瑕疵度小,那么哪个队列就更漂亮,如果一样就继续比较第i+1头奶牛。如果全部一样,那么两个队列就一样漂亮。 刚开始,奶牛们会随机站成一排,约翰每次只能要求站在最左侧的奶牛排到最右侧。他想知道,在这种情况下,可以达到的最漂亮奶牛的排列的排列方法。

Input

第一行为组数T 对于每组数据: 第一行一个整数n(n<=300000),代表奶牛的数目 第二行n个整数ai(ai<10^9),每个整数代表从左到右的每头奶牛的瑕疵度。

Output

共T行 每行输出n个整数,表示该组数据达到最优美时,从左到右每头奶牛的瑕疵度

Sample Input

1 10 10 9 8 7 6 5 4 3 2 1

Sample Output

1 10 9 8 7 6 5 4 3 2

最小表示法


做法:

设定一个i指针和j指针

i = 1,j = 2;

两个指针一只向右走

几种情况在代码中注释


CODE

#include 
using namespace std;
const int N = 300000+10;
int a[N];
int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
        int i=1,j=2;
        while(i <= n-1 && j <= n){
            if(a[i] > a[j]) i = j++;   ///i指针字符字典序大于j指针字符字典序 就一起向右移动
            else if(a[i] < a[j]) j++;  ///i指针字符字典序小于j指针字符字典序 j指针向右移动
            else{                      ///两个指针对应值相等
                int k = 0;
                while(a[i+k] == a[j+k] && j+k <= n) k++;  ///两个指针向右移动到一个不相等的点
                if(a[i+k] > a[j+k]) i = i+k+1,j = i+1;    ///i指针大于了j指针,就移向j指针,j指针对应移动
                else                j = j+k;              ///否则就只移动j指针
            }
        }
        for(int k = i;k <= n;k++) printf("%d ",a[k]);
        for(int k = 1;k < i;k++) printf("%d ",a[k]);
        puts("");
    }
    return 0;
}


你可能感兴趣的:(最小表示法)