链接:https://ac.nowcoder.com/acm/contest/5757/I
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
小明遇到了一个问题希望你能帮他解决
现在有n个数字排成一列构成数组A,数组A中存在n个数a[i], 其中1<=i<=n。
数组sj为删除数组A中的第j个数后,剩余n-1个数构成的数组,其中1<=j<=n。
小明希望你把s1~sn的数组按照字典序大小排列起来,
若两个数组相等,则认为删除元素编号小的数组字典序更小
输入描述:
输入数据第一行是t,表示数据的组数,接下来每组数据输入n,接下来一行
一共n个数,a[i]表示数组的第i个数
(t<=10,n <= 1e5,a[i] <= 1e9)
输出描述:
输出一行n个整数,b1,b2…bn,表示Sb1 < Sb2 < … < Sbn
示例1
输入
1
7
1 1 2 1 1 1 2
输出
3 7 4 5 6 1 2
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int t, n, tot;
const int maxn=1e5+5;
int a[maxn];
int b[maxn];
int ans[maxn];
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
tot = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = 0;
}
for(int i = 1; i < n; i++)
{
if(a[i] > a[i + 1])
{
int temp = i;
while(a[temp - 1] == a[temp] && temp > 1) temp--;
for(int j = temp; j <= i; j++)
{
ans[++tot] = j;
b[j] = 1;
}
}
}
// for(int i = 1; i <= n; i++)
// {
// printf("%d", ans[i]);
// if(i!=n) printf(" ");
// }
for(int i = n; i >= 1; i--)
{
if(!b[i])
{
int temp = i;
while(a[temp - 1] == a[temp] && temp > 1) temp--;
for(int j = temp; j <= i; j++)
{
ans[++tot] = j;
b[j] = 1;
}
}
}
for(int i = 1; i <= n; i++)
{
printf("%d", ans[i]);
if(i!=n) printf(" ");
}
printf("\n");
}
return 0;
}
本文介绍了一种解决小明问题的算法,该问题要求将删除数组中每个元素后得到的子数组按字典序排序。算法通过比较相邻元素,确定删除哪个元素能使子数组字典序最小,适用于竞赛编程。
866

被折叠的 条评论
为什么被折叠?



