题目:
http://acm.hdu.edu.cn/showproblem.php?pid=6215
题意:
给定一个长度为
n
的数组,满足以下条件
- 要么 a[i] 是第一个数字,要么 a[i−1]<=a[i]
- 要么
a[i]
是最后一个数字,要么
a[i]<=a[i+1]
不满足以上两个条件的 a[i] 是无序的。现在把数组的无序数字删除,剩余的数字按顺序合并,重复这个操作,直到所有数字都有序,输出最终的数组序列
思路:
直接用链表模拟,这次要删除的无序数字只可能是上次删除的无序数字的左右临近数字,根据这点优化操作
#include <bits/stdc++.h>
using namespace std;
const int N = 100000 + 10, INF = 0x3f3f3f3f;
int val[N];
int L[N], R[N];
int que[N], a[N];
int main()
{
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
val[0] = -INF, val[n+1] = INF;
L[0] = -1, R[0] = 1;
L[n+1] = n, R[n+1] = -1;
for(int i = 1; i <= n; i++)
{
scanf("%d", &val[i]);
L[i] = i-1, R[i] = i+1;
}
for(int i = 1; i <= n; i++) que[i] = i;
int num = n, en = n;
while(true)
{
bool flag = true;
int st = 1, tot = 0;
while(st <= en)
{
int x = que[st];
int cnt = 0;
while(R[x] <= n)
{
if(val[x] > val[R[x]]) x = R[x], cnt++, flag = false;
else break;
}
if(cnt)
{
num -= cnt + 1;
R[L[que[st]]] = R[x];
L[R[x]] = L[que[st]];
a[++tot] = L[que[st]];
}
while(st <= en && que[st] <= x) st++;
}
if(flag) break;
for(int i = 1; i <= tot; i++) que[i] = a[i];
en = tot;
}
printf("%d\n", num);
int x = R[0];
while(x <= n)
{
printf("%d ", val[x]);
x = R[x];
}
printf("\n");
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 100000 + 10, INF = 0x3f3f3f3f;
int val[N], L[N], R[N];
int a[N], b[N], vis[N];
int num;
void del_node(int x)
{
if(R[x] != -1 && L[x] != -1)
{
L[R[x]] = L[x];
R[L[x]] = R[x];
R[x] = L[x] = -1;
num--;
}
}
bool check(int x)
{
if(L[x] == -1) return true;
return val[L[x]] <= val[x] && val[x] <= val[R[x]];
}
int main()
{
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
val[0] = -INF, val[n+1] = INF;
L[0] = -1, R[0] = 1;
L[n+1] = n, R[n+1] = -1;
for(int i = 1; i <= n; i++)
{
scanf("%d", &val[i]);
L[i] = i-1, R[i] = i+1;
}
for(int i = 1; i <= n; i++) a[i] = i;
num = n;
while(true)
{
bool flag = true;
int k = 0;
for(int i = 1; i <= n; i++)
if(! check(a[i])) b[++k] = a[i], flag = false;
if(flag) break;
int tk = 0;
for(int i = 1; i <= k; i++)
{
if(val[L[b[i]]] != -INF && val[L[b[i]]] <= val[b[i]])
a[++tk] = L[b[i]];
if(val[R[b[i]]] != INF && val[R[b[i]]] >= val[b[i]])
a[++tk] = R[b[i]];
}
for(int i = 1; i <= k; i++) del_node(b[i]);
n = tk;
}
printf("%d\n", num);
int x = R[0];
while(val[x] != INF) printf("%d ", val[x]), x = R[x];
printf("\n");
}
return 0;
}